"""
Copyright 2008 Olivier Belanger

This file is part of Ounk.

Ounk is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Ounk is distributed in the hope that it will be useful,
but WITHOUT ANY WA3ANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Ounk.  If not, see <http://www.gnu.org/licenses/>.
"""

# TODO: need to be fully tested with and without midiSynth....
#       midiSynth in myInstrument 
#       csIf - csElif - csElse structure (csIf2... for two bus comparison)
# midi device (adding -+rtmidi, taking care of alsa (hw:1,0))

import sys, os, string, math, wave, random, signal, time
from types import ListType, IntType, FloatType, BooleanType, StringType, TupleType
from subprocess import Popen, PIPE
from ounk.MyTimer import MyTimer
from ounk.RhythmPattern import RhythmPattern
from ounk.Liner import Liner
from ounk.OneCall import OneCall
from ounk.Drunk import *
from ounk.Markov import Markov
from ounk.Attractors import *
import ounk.osc as osc
from ounk.UDO import udoDict
from distutils.sysconfig import get_python_lib

# PATHS #
ounk_as_lib = False
if '/Ounk.app' in os.getcwd():
    osc.init()
    currentw = os.getcwd()
    spindex = currentw.index('/Ounk.app')
    newcurrentw = currentw[:spindex]
    resources_path = currentw
    sound_path = os.path.join(newcurrentw, 'files', 'snds')
    impulse_path = os.path.join(newcurrentw, 'files', 'impulses')
    soundfont_path = os.path.join(newcurrentw, 'files', 'soundfonts')
    midi_path = os.path.join(newcurrentw, 'files', 'midi')
    settings_path = os.path.join(newcurrentw, 'settings')
elif os.path.isfile(os.path.join(os.getcwd(), 'ounk', 'ounklib.py')):
    osc.init()
    resources_path = os.path.join(os.getcwd(), 'ounk')
    sound_path = os.path.join(os.getcwd(), 'files', 'snds')
    impulse_path = os.path.join(os.getcwd(), 'files', 'impulses')
    soundfont_path = os.path.join(os.getcwd(), 'files', 'soundfonts')
    midi_path = os.path.join(os.getcwd(), 'files', 'midi')
    settings_path = os.path.join(os.getcwd(), 'settings')
else:
    ounk_as_lib = True
    resources_path = os.path.join(get_python_lib(), 'ounk')
    sound_path = os.path.expanduser('~')
    impulse_path = os.path.expanduser('~')
    soundfont_path = os.path.expanduser('~')
    midi_path = os.path.expanduser('~')
    settings_path = os.path.join(get_python_lib(), 'ounk', 'settings')

temp_path = os.path.join(os.path.expanduser('~'), '.ounk')
if not os.path.isdir(temp_path):
    os.mkdir(temp_path)

project_paths = []

###################################################
################# Initialisation ##################

# Initialisation of command-line flags for csound
systemPlatform = sys.platform

#if systemPlatform == 'darwin':
#    from Resources.HIDevice import HIDevice
        
conf = {}

def _settings(file):
    try:
        f = open(os.path.join(settings_path, file), 'r')
    except:
        f = open(os.path.join(resources_path, file), 'r')
    for line in f.readlines():
        if line[0] != '#':
            l = line.strip().split('=')
            if len(l) > 1:
                conf[l[0].strip()] = eval(l[1].strip())
    f.close()

def _libsettings():
    global conf
    if systemPlatform == 'darwin':
        conf = {'sr': 44100,
                'kr': 4410,
                'softBuffer': 250,
                'hardBuffer': 500,
                'audioFormat': 'aif',
                'driver': 'portaudio',
                'sampleFormat': '',
                'audioInputNumber': '',
                'audioOutputNumber': ''}
    elif systemPlatform == 'win32':
        conf = {'sr': 44100,
                'kr': 4410,
                'softBuffer': 256,
                'hardBuffer': 4096,
                'audioFormat': 'wav',
                'driver': 'portaudio',
                'sampleFormat': '',
                'audioInputNumber': '',
                'audioOutputNumber': ''}
    else:
        conf = {'sr': 44100,
                'kr': 4410,
                'softBuffer': 512,
                'hardBuffer': 2048,
                'audioFormat': 'wav',
                'driver': 'portaudio',
                'sampleFormat': '',
                'audioInputNumber': '',
                'audioOutputNumber': ''}
    
def _init():
    global sr, kr, softBuf, hardBuf, format, auFormat, driver, audiodevin, audiodevout

    if not ounk_as_lib:
        if systemPlatform == 'darwin':
            _settings('config_darwin.py')
        elif systemPlatform == 'win32':
            _settings('config_win32.py')
        else:
            _settings('config_linux.py')
    else:
        _libsettings()
    sr = conf['sr']                    # sampling rate
    kr = conf['kr']                    # control rate (sr/kr must egal integer)
    softBuf = conf['softBuffer']       # i/o software buffer
    hardBuf = conf['hardBuffer']       # i/o hardware buffer
    format = conf['sampleFormat']      # sample format: '' = 16 bits, '-3' = 24 bits, '-f' = 32 bits float
    auFormat = conf['audioFormat']
    driver = conf['driver']
    audiodevin = conf['audioInputNumber']      # Audio device number for input (default to 0)
    audiodevout = conf['audioOutputNumber']    # Audio device number for output (default to 0)

_init()

nchnls = 2                  # global number of channels
usednchnls = []             # list of used channels in a script
outnchnls = None            # output number of channels

display = ''                # '--display' gives a window for mouse controller
midi = ''                   # midi input
mididev = 0                 # Midi device number

midifile = ''               # midifile
inadc = ''                  # microphone input
###################################################

# Chords and scales dictionaries
chords = {}
scales = {}
def _chordsAndScales():
    global chords, scales
    try:
        f = open(os.path.join(settings_path, 'chords.py'), 'r')
    except:
        f = open(os.path.join(resources_path, 'chords.py'), 'r')        
    for line in f.readlines():
        if line[0] != '#':
            l = line.strip().split('=')
            if len(l) > 1:
                chords[l[0].strip()] = eval(l[1].strip())
    f.close()
   
    try:
        f = open(os.path.join(settings_path, 'scales.py'), 'r')
    except:
        f = open(os.path.join(resources_path, 'scales.py'), 'r')
    for line in f.readlines():
        if line[0] != '#':
            l = line.strip().split('=')
            if len(l) > 1:
                scales[l[0].strip()] = eval(l[1].strip())
    f.close()

if not ounk_as_lib:
    _chordsAndScales()
    
# variables
processDict = {}            # Dictionary of running csound processes
procNum = 1                 # Process number

orchlines = []              # list of orchestra lines
scorelines = []             # list of score lines
seqlines = []               # list of sequencer lines
triglines = []              # list of triggered inst lines
trigheadlines = []          # list of triggered inst header lines
pythonlines = {}            # dictionary of lists of python instrument event lines
pythonlines[procNum] = {}   # each process needs a dictionary
soundfontlines = []         # list of header soundfonts lines
soundfontsUsed = {}         # ditionary of soundfonts used in a script {'sondfont': engine_number}
instrlist = []              # list of used instruments
instrumentDict = {}         # dictionnary of instrument_name: instrument_numbers
instrumentDict[procNum] = {} # each process needs a dictionary
newInstrument = 16          # first instrument == 17 (1 to 16 are reserved for midi channels)
lastInstrument = ''         # string identifing last instrument writed
fracPart = 0                # fractional part of score instrument number for infinite duration
fnum = 100                  # next ftable number
sndnum = 1000               # next sound ftable number
zakindex = {}               # dictionnary for audio channels (value_assign_to_out: channel_number)
kratebus = {}               # dictionnary for control channels (value_assign_to_bus: channel_number)

guiDict = {}                # dictionary of GUI frames
guiDict[procNum] = []       # each process needs a list to handle multiple frames

UDO = []                    # list of user defined opcode
GDUR = -1                   # global duration

oscPort = []                # list of open sound control ports

cspipeDict = {}             # csound pipe dictionary
cspid = None                # csound process id

patternDict = {}            # Dictionary of pattern threads list to be stoped at the end of performance. dict = {procNum: [pat1, pat2, ...]}
patternDict[procNum] = []

dataTableLen = {}           # Length of tables generated by genDataTable
dataTableLen[procNum] = {}  # and genDiscreetTable (used in table overriding)

# midi synth variables
midiSynthesizer = False     # flag that indicates if we are inside midi synth definition
midiSynthesizerChannel = [] # list of midi channels used
midiRelease = 1             # midi synth release time
keyboardSplit = False       # flag that indicates we are difining a keyboard region in a midi synth
velocitySplit = False       # flag that indicates we are defining a velocity region in a midi synth
midiInstBusAudio = []       # list of audio channels inside a midi synth
midiInstOutAudio = []       # list of audio sends to output of a midi synth

# sequencer variables
sequencer = False           # flag that indicates if we are inside a sequencer definition
seqInstrument = None        # sequencer instrument number
seqPitchTable = None        # current sequencer pitch table
seqParamsTable = []         # list of current sequencer parameter tables
paramDict = {}              # dictionnary of function parameters {instrument: [list_of_parameters]}
paramDict[procNum] = {}     # each process needs a dictionary
stringSetDict = {}          # dictionary of stringset for sound paths

# triggered inst variables
triggeredInst = False
trigInstrument = None
trigRelease = None

# loop variables
insideLoop = False
loopStart = 0
loopDur = None
loopLegato = None
loopAmplitude = None

# python instrument
pythonInst = False

# soundfont variables
insideSoundfont = False

# performance recording variables
liveRec = False             # flag that indicates if we want to record performance
perfDuration = 1            # duration of the recording
perfName = ''               # name of the audio file

voiceSynthesis = False      # boolean, flag that indicates we are inside voice synthesis definition
voiceTables = False         # boolean, flag that indicates we need voices syntesis ftables

# ladspa plugins
ladspaPlugin = False       # boolean, tells Ounk not to play sound but to build csladspa plugin
ladspaDict = {}            # dictionnary {'pluginName': [bus, min, max, log(boolean)]}
ladspaName = 'Ounk plugin' # plugin default name

# output configuration
usedPanners = []           # list of panners to create
pannerlines = []           # panners creation
# speakers order
SPEAKERS = range(64)    

# frame where to pack object with "with Gui"
currentFrame = None

####################################################
############# Miscellaneous functions ##############
def projectPath(path):
    """Adds project path to the files search paths."""
    project_paths.append(path)
    
def setSoundPath(path):
    """Sets the path to the audio file folder.

path = 'currentDir/snds'
"""
    global sound_path
    sound_path = path

def setImpulsePath(path):
    """Sets path of the impulse response files folder.

path = 'currentDir/impulses'
"""
    global impulse_path
    impulse_path = path

def setSoundfontPath(path):
    """Sets the path to the soundfonts folder.

path = 'currentDir/soundfonts'
"""
    global soundfont_path
    soundfont_path = path

def setMidiPath(path):
    """Sets the path to the midi folder.

path = 'currentDir/midi'
"""
    global midi_path
    midi_path = path

def getSoundPath():
    """Prints the sound path to the console and returns it"""
    print 'Sound path: %s' % sound_path
    return sound_path

def getImpulsePath():
    """Prints impulse path to the console and returns it."""
    print 'Impulse path: %s' % impulse_path
    return impulse_path

def getSoundfontPath():
    """Prints the soundfont path to the console and returns it"""
    print 'Soundfont path: %s' % soundfont_path
    return soundfont_path

def getMidiPath():
    """Prints midi path to the console and returns it."""
    print 'Midi path: %s' % midi_path
    return midi_path

def getSoundList():
    """Prints sounds list to the console and returns it."""
    print sorted(os.listdir(sound_path))
    return sorted(os.listdir(sound_path))

def getSoundInfo(sound):
    """Retrieves information of the sound and prints it to the console.

return (number of channels, sampling rate, duration, fraction of a table, length in samples, bitrate)"""
    fullname = None
    if os.path.isfile(sound):
        fullname = sound
    elif project_paths:
        for path in project_paths:
            if os.path.isfile(os.path.join(path, sound)):
                fullname = os.path.join(path, sound)
                break
    if not fullname:
        fullname = os.path.join(sound_path, sound)

    cschnls = {'monaural': 1, 'stereo': 2, 'quad': 4, 'oct': 8}

    if systemPlatform == 'darwin':
        ret = Popen('/usr/local/bin/csound --logfile=%s -U sndinfo "%s"' % (os.path.join(temp_path, 'sndlog.txt'), fullname), shell=True)
    elif systemPlatform == 'win32':
        ret = Popen('start /B /REALTIME /WAIT csound --logfile="%s" -U sndinfo "%s"' % (os.path.join(temp_path, 'sndlog.txt'), fullname), shell=True)
    else:
        ret = Popen('csound --logfile=%s -U sndinfo "%s"' % (os.path.join(temp_path, 'sndlog.txt'), fullname), shell=True)
     
    s = ret.wait()    
    #s = os.waitpid(ret.pid, 0)
    
    f = open(os.path.join(temp_path, 'sndlog.txt'), 'r')
    text = f.read()
    f.close()
    os.remove(os.path.join(temp_path, 'sndlog.txt'))
    
    sp = text.split('srate')[-1]
    sp = sp.replace(',', '').replace('(', '').replace(')', '').replace('\n', ' ').replace('\t', '').strip()
    sp = sp.split(' ')   
    
    samprate = eval(sp[0])
    chnls = cschnls[sp[1]]
    dur = eval(sp[sp.index('seconds')-1])
    nsamps = eval(sp[sp.index('sample')-1])
    bitrate = eval(sp[sp.index('bit')-1])
    for i in range(24):
        size = math.pow(2,(i+1))
        if size > nsamps:
            break
    tableFrac = nsamps / size
        
    print "channels = %d" % chnls
    print "sampling rate = %s" % samprate
    print "number of samples = %s" % nsamps
    print "duration in sec. = %s" % dur
    print "bitrate = %s" % bitrate

    return (chnls, samprate, dur, tableFrac, nsamps, bitrate)

def setAudioAttributes(samplingrate=None, controlrate=None, softbuffer=None, hardbuffer=None, sampleformat=None, audioformat=None, audiodriver=None):
    """Sets audio attributes.

samplingrate = None
controlrate = None
softbuffer = None
hardbuffer = None
sampleformat = None # 16, 24 or 32
audioformat = None # 'wav' or 'aif'
audiodriver = None

Must be called only once per script!"""
    global sr, kr, softBuf, hardBuf, format, auFormat, driver
    if samplingrate:
        sr = samplingrate
    if controlrate:
        kr = controlrate
    if softbuffer:    
        softBuf = softbuffer
    if hardbuffer:    
        hardBuf = hardbuffer
    if audioformat:
        auFormat = audioformat.lower()
    if audiodriver:    
        driver = audiodriver
    if sampleformat:    
        if sampleformat == 24:
            format = '-3'
        elif sampleformat == 32:
            format = '-f'
        else:
            format = ''

def getAudioAttributes():
    """Prints audio attributes to the console."""
    print "sampling rate = %d" % sr
    print "control rate = %d" % kr
    print "number of channels = %d" % nchnls
    print "soft buffer = %d" % softBuf
    print "hard buffer = %d" % hardBuf
    if format == '-3':
        print "sample format = 24 bits"
    elif format == '-f':
        print "sample format = 32 bits float"
    else:
        print "sample format == 16 bits"
    print "audio format = %s" % auFormat
    print "audio driver = %s" % driver

def clear():
    """Clears global variables."""
    global orchlines, scorelines, seqlines, soundfontlines, instrlist, newInstrument, lastInstrument, liveRec, insideSoundfont, stringSetDict
    global fracPart, fnum, sndnum, zakindex, kratebus, keyboardSplit, velocitySplit, seqPitchTable, voiceTables, inadc, SPEAKERS
    global midifile, pythonInst, oscPort, display, midiSynthesizerChannel, GDUR, midi, outnchnls, usednchnls, mididev, soundfontsUsed, usedPanners
    global nchnls, sound_path, impulse_path, soundfont_path, midi_path, UDO, cspid, ladspaPlugin, ladspaDict, ladspaName, chords, scales, pannerlines
    global triglines, trigheadlines, triggeredInst, trigInstrument, trigRelease
    
    orchlines = []
    scorelines = []
    seqlines = []
    triglines = []
    trigheadlines = []
    soundfontlines = []
    soundfontsUsed = {}
    instrlist = []
    newInstrument = 16
    lastInstrument = ''
    pythonInst = False
    triggeredInst = False
    trigInstrument = None
    trigRelease = None
    liveRec = False
    insideSoundfont = False
    fracPart = 0
    fnum = 100
    sndnum = 1000
    zakindex = {}
    kratebus = {}
    keyboardSplit = False
    velocitySplit = False
    seqPitchTable = None
    stringSetDict = {}
    voiceTables = False
    ladspaPlugin = False
    ladspaDict = {}
    ladspaName = 'Ounk plugin'
    display = ''
    inadc = ''
    midifile = ''
    midi = ''
    mididev = 0
    usedPanners = []
    pannerlines = []
    SPEAKERS = range(64)
    oscPort = []
    midiSynthesizerChannel = []
    GDUR = -1
    nchnls = 2
    usednchnls = []
    outnchnls = None
    chords = {}
    scales = {}
    _init()
    if not ounk_as_lib:
        _chordsAndScales()
    if '/Ounk.app' in os.getcwd():
        currentw = os.getcwd()
        spindex = currentw.index('/Ounk.app')
        newcurrentw = currentw[:spindex]
        resources_path = currentw
        sound_path = os.path.join(newcurrentw, 'files', 'snds')
        impulse_path = os.path.join(newcurrentw, 'files', 'impulses')
        soundfont_path = os.path.join(newcurrentw, 'files', 'soundfonts')
        midi_path = os.path.join(newcurrentw, 'files', 'midi')
        settings_path = os.path.join(newcurrentw, 'settings')
    elif os.path.isfile(os.path.join(os.getcwd(), 'ounk', 'ounklib.py')):
        resources_path = os.path.join(os.getcwd(), 'ounk')
        sound_path = os.path.join(os.getcwd(), 'files', 'snds')
        impulse_path = os.path.join(os.getcwd(), 'files', 'impulses')
        soundfont_path = os.path.join(os.getcwd(), 'files', 'soundfonts')
        midi_path = os.path.join(os.getcwd(), 'files', 'midi')
        settings_path = os.path.join(os.getcwd(), 'settings')
    else:
        resources_path = os.path.join(get_python_lib(), 'ounk')
        sound_path = os.path.expanduser('~')
        impulse_path = os.path.expanduser('~')
        soundfont_path = os.path.expanduser('~')
        midi_path = os.path.expanduser('~')
        settings_path = os.path.join(get_python_lib(), 'ounk', 'settings')
    UDO = []
    
def setGlobalDuration(dur):
    """Sets the global duration. If a function duration is None, the global duration is used.
    
dur = global_duration

--- PARAMETERS ---

dur : Global duration of the script in seconds.
"""
    global GDUR
    GDUR = dur

def setMidiDevice(number):
    """Sets the input number of the desired Midi device. See the Csound log to know which devices connected."""
    global mididev
    mididev = number

def setAudioDevice(inumber=None, onumber=None):
    """Sets the input number of the desired Audio device. See the Csound log to know which devices connected. If None Csound will try its default value.
    
inumber = None
onumber = None
"""
    global audiodevin, audiodevout
    if inumber:
        audiodevin = inumber
    else:
        audiodevin = ''
    if onumber:
        audiodevout = onumber
    else:
        audiodevout = ''

def setChannels(channels=2):
    """Changes the number of channels used by functions to set inputs and outputs. Can be used any number of times in a script.
    
channels = 2 # 1, 2, 4 or 8
"""
    global nchnls
    nchnls = channels
    usednchnls.append(channels)
 
def speakersConfig(*args):
    """Changes the order of output numbers. Number of arguments must fit number of used outputs. Speaker numbers begin at 0.
    
arg1, arg2, arg3, ... = new_order"""
    global SPEAKERS
    length = len(args)
    SPEAKERS = [args[i] for i in range(length)]

def recordPerf(name='perf', duration=None, nameinc=True):
    """Records the performance.

name = 'perf'
duration = None
nameinc = True
"""
    global liveRec, perfName, perfDuration

    if not duration: duration = GDUR
    liveRec = True
    perfName = name
    perfDuration = duration
    _perfRecorder(_checkChannels(), nameinc)


#####################################################
############# General private functions #############
def _output(duration=None, activeChannels=None, amplitude=1, nosound=False, withevents=True):

    if not duration: duration = GDUR

    if amplitude == 1:
        _masterOutAmplitude = ''
    else:
        _masterOutAmplitude = ' * %s' % amplitude
     
    order = [SPEAKERS.index(i) for i in range(len(SPEAKERS))]
    
    orchlines.append("instr 10000\n")

    orchlines.append('OSCsend 1, "127.0.0.1", 15000, "/csound_ready", "i", 1\n')

    if withevents:
        port = str(16000 + procNum)
        oscPort.append(port) 
        orchlines.append('Smes = ""\n')
        orchlines.append('kk OSClisten gi%s, "/event", "s", Smes\n' % port)
        orchlines.append("if kk == 1 then\n")
        orchlines.append("scoreline Smes, 1\n")
        orchlines.append("endif\n")

    for i in range(activeChannels):
        orchlines.append("aout%d = gaout%d%s\n" % (i,i,_masterOutAmplitude))
    if not nosound:    
        orchlines.append('outc ' + ', '.join(['aout%d' % order[i] for i in range(activeChannels)]) + "\n")
    if liveRec:
        for i in range(activeChannels):
            orchlines.append("garec%d = aout%d\n" % (i,order[i]))

    for i in range(activeChannels):
        orchlines.append("gaout%d = 0\n" % i)
    if len(zakindex) > 0:
        orchlines.append("zacl 1, %d\n" % max(zakindex.values()))
    if voiceTables:
        orchlines.append("gaNoise pinkish 1\n")
    orchlines.append("endin\n\n")
    scorelines.append("i10000 0 %s\n" % str(duration))
    #if liveRec:
    #    _perfRecorder(activeChannels)
    return activeChannels    

def _perfRecorder(activeChannels, nameinc):
    if auFormat == 'wav': first = 10
    else: first = 20
    if format == '-f': second = 6
    elif format == '-3': second = 8
    else: second = 4
    fileType = first + second

    outfile = os.path.join(sound_path, perfName) + ".%s" % auFormat
    if os.path.isfile(outfile) and nameinc:
        listdir = os.listdir(sound_path)
        samefile = [f for f in listdir if str(perfName) in f]
        fileinc = len(samefile)
        outfile = os.path.join(sound_path, perfName) + "-%d.%s" % (fileinc, auFormat)

    orchlines.append('instr 10001\nSname strcpy "%s"\n' % outfile)

    for i in range(activeChannels):
        orchlines.append("garec%d init 0\n" % i)
    orchlines.append("ihandle fiopen Sname, 2\n")
    
    orchlines.append('fout Sname, %d, '  % fileType + ', '.join(['garec%d' % i for i in range(activeChannels)]) + '\n')
    orchlines.append('clear ' + ', '.join(['garec%d' % i for i in range(activeChannels)]) + '\n')

    orchlines.append("endin\n\n")
    orchlines.append('instr 10002\nSname strcpy "%s"\n' % outfile)
    orchlines.append("ficlose Sname\nendin\n\n")
    _routeScoreline("i10001 0 %s\n" % str(perfDuration))
    if perfDuration != -1:
        _routeScoreline("i10002 %s 0.1\n" % str(perfDuration))
    #scorelines.append("i10001 0 %s\n" % str(perfDuration))
    #scorelines.append("110002 %s 0.1\n" % str(perfDuration))
        
#### Panoramisation functions ####
def _outPanSig(out, outpval, ipanpval, pan, numinputs, numoutputs, spread=0, offset=0):
    panner = 'panner%d' % numoutputs
    if panner not in usedPanners and numoutputs > 2:
        usedPanners.append(panner)
        _createPanner(panner, numoutputs)
        
    if pan == '' and numoutputs <= 2: 
        panvalue1 = 'sqrt(1 - p%d)' % ipanpval
        panvalue2 = 'sqrt(p%d)' % ipanpval
    elif pan == '' and numoutputs > 2:
        panvalue = 'p%d' % ipanpval
    elif numoutputs <= 2:
        orchlines.append("idump = p%d\n" % ipanpval)
        panvalue1 = 'sqrt(1 - %s)' % pan
        panvalue2 = 'sqrt(%s)' % pan
    else:    
        orchlines.append("idump = p%d\n" % ipanpval)
        panvalue = '%s' % pan

    if numoutputs == 1:
        insig = ['a%d' % i for i in range(numinputs)]
        totalin = '(' + ' + '.join(insig) + ')' + ' * ' + str(math.sqrt(1./len(insig)))
        if triggeredInst and trigRelease:
            orchlines.append("ktrigenv linenr 1, 0, %s, .005\n" % trigRelease)
            trigrel = ' * ktrigenv'
        else:
            trigrel = ''
        if out == 'dac':
            orchlines.append("gaout0 = %s%s + gaout0\n" % (totalin, trigrel))
        else:
            orchlines.append("zawm %s%s, p%d\n" % (totalin, trigrel, outpval))
    elif numoutputs == 2:
        if numinputs == 1: 
            insig1 = insig2 = ['a0']
        else:
            insig1 = ['a%d' % i for i in range(numinputs) if i%2 == 0]
            insig2 = ['a%d' % i for i in range(numinputs) if i%2 == 1]
        totalin1 = '(' + ' + '.join(insig1) + ')' + ' * ' + str(math.sqrt(1./len(insig1)))
        totalin2 = '(' + ' + '.join(insig2) + ')' + ' * ' + str(math.sqrt(1./len(insig2)))
        if triggeredInst and trigRelease:
            orchlines.append("ktrigenv linenr 1, 0, %s, .005\n" % trigRelease)
            trigrel = ' * ktrigenv'
        else:
            trigrel = ''
        if out == 'dac':
            orchlines.append("gaout0 = %s * %s%s + gaout0\ngaout1 = %s * %s%s + gaout1\n" % (totalin1, panvalue1, trigrel, totalin2, panvalue2, trigrel))
        else:
            orchlines.append("zawm %s * %s%s, p%d-1\nzawm %s * %s%s, p%d\n" % (totalin1, panvalue1, trigrel, outpval, totalin2, panvalue2, trigrel, outpval))
    else:
        if triggeredInst and trigRelease:
            orchlines.append("ktrigenv linenr 1, 0, %s, .005\n" % trigRelease)
            trigrel = ' * ktrigenv'
        else:
            trigrel = ''
        for i in range(numinputs):    
            if numinputs == 1:
                insig = ['a0']
            elif numinputs < numoutputs:
                insig = ['a%d' % (i % numinputs)]
            else:
                insig = ['a%d' % j for j in range(numinputs) if j % numoutputs == i]
            totalin = '(' + ' + '.join(insig) + ')' + ' * ' + str(math.sqrt(1./len(insig)))
            pannerouts = ', '.join(['aoutpan%d%d' % (i,j) for j in range(numoutputs)])
            if i == 0:
                off = 0
            else:
                if offset == 0:
                    off = (i*(1./numoutputs))
                else:
                    off = (i*(1./numoutputs)) + (offset - (1./numoutputs))
            orchlines.append("%s %s %s, %s, %s, %s\n" % (pannerouts, panner, totalin, panvalue, spread, off))
        for i in range(numoutputs):
            addedVoices = '(' + ' + '.join(['aoutpan%d%d' % (j,i) for j in range(numinputs)]) + ')'
            if out == 'dac':
                orchlines.append("gaout%d = %s%s + gaout%d\n" % (i, addedVoices, trigrel, i))
            else:
                orchlines.append("zawm %s%s, p%d-%d\n" % (addedVoices, trigrel, outpval, numoutputs-1-i))
    if voiceSynthesis:
        orchlines.append("tieSkip:\nendin\n\n")
    else:
        orchlines.append("endin\n\n")

def _outPanMidiSig(num, out, ipan, pan, numinputs, numoutputs, spread=0, offset=0):
    panner = 'panner%d' % numoutputs
    if panner not in usedPanners and numoutputs > 2:
        usedPanners.append(panner)
        _createPanner(panner, numoutputs)
        
    if not pan and numoutputs <= 2: 
        panvalue1 = 'sqrt(1 - %s)' % _wrap(ipan, num)
        panvalue2 = 'sqrt(%s)' % _wrap(ipan, num)
    elif not pan and numoutputs > 2:
        panvalue = '%s' % _wrap(ipan, num)
    elif numoutputs <= 2:
        panvalue1 = 'sqrt(1 - kbus%s)' % _wrap(pan, num)
        panvalue2 = 'sqrt(kbus%s)' % _wrap(pan, num)
    else:    
        panvalue = 'kbus%s' % _wrap(pan, num)

    if numoutputs == 1:
        insig = ['a%d%d' % (i, num) for i in range(numinputs)]
        totalin = '(' + ' + '.join(insig) + ')' + ' * ' + str(math.sqrt(1./len(insig)))
        if out == 'dac':
            orchlines.append("gamidiout0%d = %s + gamidiout0%d\n" % (num, totalin, num))
            if num not in midiInstOutAudio:
                midiInstOutAudio.append(num)
        else:
            orchlines.append("abus0%s = %s + abus0%s\n" % (str(out), totalin, str(out)))
            if str(out) not in midiInstBusAudio:
                midiInstBusAudio.append(str(out))
    elif numoutputs == 2:
        if numinputs == 1: 
            insig1 = insig2 = ['a0%d' % num]
        else:
            insig1 = ['a%d%d' % (i, num) for i in range(numinputs) if i%2 == 0]
            insig2 = ['a%d%d' % (i, num) for i in range(numinputs) if i%2 == 1]
        totalin1 = '(' + ' + '.join(insig1) + ')' + ' * ' + str(math.sqrt(1./len(insig1)))
        totalin2 = '(' + ' + '.join(insig2) + ')' + ' * ' + str(math.sqrt(1./len(insig2)))        
        if out == 'dac':
            orchlines.append("gamidiout0%d = %s * %s + gamidiout0%d\n" % (num, totalin1, panvalue1, num))
            orchlines.append("gamidiout1%d = %s * %s + gamidiout1%d\n" % (num, totalin2, panvalue2, num))
            if num not in midiInstOutAudio:
                midiInstOutAudio.append(num)
        else:
            orchlines.append("abus0%s = %s * %s + abus0%s\n" % (str(out), totalin1, panvalue1, str(out)))
            orchlines.append("abus1%s = %s * %s + abus1%s\n" % (str(out), totalin2, panvalue2, str(out)))
            if str(out) not in midiInstBusAudio:
                midiInstBusAudio.append(str(out))
    else:
        for i in range(numinputs):    
            if numinputs == 1:
                insig = ['a0%d' % num]
            elif numinputs < numoutputs:
                insig = ['a%d%d' % ((i % numinputs), num)]
            else:
                insig = ['a%d%d' % (j, num) for j in range(numinputs) if j % numoutputs == i]
            totalin = '(' + ' + '.join(insig) + ')' + ' * ' + str(math.sqrt(1./len(insig)))
            pannerouts = ', '.join(['aoutpan%d%d' % (i,j) for j in range(numoutputs)])
            if i == 0:
                off = 0
            else:
                if offset == 0:
                    off = (i*(1./numoutputs))
                else:
                    off = (i*(1./numoutputs)) + (offset - (1./numoutputs))
            orchlines.append("%s %s %s, %s, %s, %s\n" % (pannerouts, panner, totalin, panvalue, spread, off))
        for i in range(numoutputs):
            addedVoices = '(' + ' + '.join(['aoutpan%d%d' % (j,i) for j in range(numinputs)]) + ')'
            if out == 'dac':
                orchlines.append("gamidiout%d%d = %s + gamidiout%d%d\n" % (i, num, addedVoices, i, num))
                if num not in midiInstOutAudio:
                    midiInstOutAudio.append(num)
            else:
                orchlines.append("abus%d%s = %s + abus%d%s\n" % (i, str(out), addedVoices, i, str(out)))
                if str(out) not in midiInstBusAudio:
                    midiInstBusAudio.append(str(out))
            
def _createPanner(name, numoutputs):
    dist = 1. / numoutputs
    pannerlines.append("opcode %s, %s, akki\n" % (name, ('a'*numoutputs)))
    pannerlines.append("ain, kpan, kspread, ioffset xin\n")
    pannerlines.append("kp wrap kpan, 0, 1\n")
    pannerlines.append("ksp wrap kspread, 0, 1.00001\n")
    pannerlines.append("ksprd scale 1-sqrt(ksp), 50, 1\n")
    for i in range(numoutputs):
        pannerlines.append("k%d pow cos((kp - %f + ioffset) * 6.28308) * 0.5 + 0.5, ksprd\n" % (i, (i*dist)))
        pannerlines.append("a%d = ain * k%d\n" % (i, i))
    pannerlines.append('xout ' + ','.join(['a%d' % i for i in range(numoutputs)]) + '\n')
    pannerlines.append('endop\n\n')

# redundant calls
def _initAudioBusMidi(out):
    if out != 'dac':
        for i in range(_checkChannels()):
            orchlines.append("abus%d%s init 0\n" % (i, str(out)))

def _convertToList(*args):
    if len(args) == 1:
        i = args[0]
        if type(i) != ListType: i = [i]
        return i
    first = True
    for i in args:
        if type(i) != ListType: i = [i]
        if first:
            tup = (i,)
        else:
            tup = tup + (i,)
        first = False
    return tup

def _convertVarToList(*args):
    if len(args) == 1:
        i = args[0]
        if i != None and type(i) != ListType: i = [i]
        return i
    first = True
    for i in args:
        if i != None and type(i) != ListType: i = [i]
        if first:
            tup = (i,)
        else:
            tup = tup + (i,)
        first = False
    return tup

def _wrap(para, i):
    return para[i%len(para)]

def _len(i):
    if not i: return 0
    else: return len(i)

def _setpan(pval):
    ipanpval = pval
    pval += 1
    return ipanpval, pval

def _setpanVar(pval):
    orchlines.append('Spankbus sprintf "kbus%d"')
    orchlines.append(", p%d\n" % pval)
    orchlines.append("kpan chnget Spankbus\n")
    pval += 1
    panval = 'kpan'
    return pval, panval

def _setspreadVar(pval):
    orchlines.append('Sspreadkbus sprintf "kbus%d"')
    orchlines.append(", p%d\n" % pval)
    orchlines.append("kspread chnget Sspreadkbus\n")
    pval += 1
    spreadval = 'kspread'
    return pval, spreadval

def _setenvelope(pval):
    orchlines.append("kenv oscil1i 0, 1, p3, p%d\n" % pval)
    pval += 1
    env = '*kenv'
    return pval, env

def _setVar(pval, key):
    orchlines.append('S%skbus ' % key)
    orchlines.append('sprintf "kbus%d"')
    orchlines.append(", p%d\n" % pval)
    orchlines.append("k%s chnget S%skbus\n" % (key, key))
    pval += 1
    return pval

def _setxxxVar(pval, key):
    orchlines.append('S%skbus ' % key)
    orchlines.append('sprintf "kbus%d"')
    orchlines.append(", p%d\n" % pval)
    orchlines.append("k%s chnget S%skbus\n" % (key, key))
    pval += 1
    val = '*k%s' % key
    return pval, val

def _setadelVar(pval, key):
    orchlines.append('S%skbus ' % key)
    orchlines.append('sprintf "kbus%d"')
    orchlines.append(", p%d\n" % pval)
    orchlines.append("k%s chnget S%skbus\n" % (key, key))
    orchlines.append("a%s interp k%s\n" % (key, key))
    pval += 1
    val = '*a%s' % key
    return pval, val

def _checkTrigged():
    if triggeredInst and trigRelease:
        orchlines.append("xtratim %s\n" % trigRelease)

def _checkChannels():
    return nchnls

def _whichVars(list):
    e = 0
    for i in range(len(list)):
        if list[i] != None:
            e += math.pow(2,i)
    return e

def _checkInst(str, index, ctl=False):
    global instrumentDict, newInstrument, lastInstrument

    ########################################
    # BIG BIG HACK (NEED A BETTER SOLUTION!)
    #ctl = True
    ########################################
    #if str == 'voiceSynth': print ctl, pythonInst, index
    
    if triggeredInst: 
        ctl = True
    
    if str == 'soundfontMidi':
        newInstrument += 1
        return newInstrument
    if not ctl and not pythonInst:
        if str in instrumentDict[procNum]:
            if index in instrumentDict[procNum][str] and str == lastInstrument:
                inst = instrumentDict[procNum][str][index]
            elif index in instrumentDict[procNum][str]:
                newInstrument += 1
                instrumentDict[procNum][str][index] = newInstrument
                inst = newInstrument
            else:
                # why +1000 and not index?
                newInstrument += 1
                #instrumentDict[procNum][str][len(instrumentDict[procNum][str])+1000] = newInstrument
                instrumentDict[procNum][str][index] = newInstrument
                inst = newInstrument
        else:
            newInstrument += 1
            instrumentDict[procNum][str] = {}
            instrumentDict[procNum][str][index] = newInstrument
            inst = newInstrument
        lastInstrument = str
    else:
        if str in instrumentDict[procNum]:
            newInstrument += 1
            instrumentDict[procNum][str][len(instrumentDict[procNum][str])+2000] = newInstrument
            inst = newInstrument
        else:
            newInstrument += 1
            instrumentDict[procNum][str] = {}
            instrumentDict[procNum][str][0] = newInstrument
            inst = newInstrument
        lastInstrument = None     
    return inst           

def _infinite():
    global fracPart
    fracPart += 0.0001
    return fracPart

def _kbusset(bus):
    bus = str(bus)
    if bus not in kratebus.keys():
        value = len(kratebus) + 1
        kratebus[bus] = value
        return value
    else:
        return kratebus[bus]

def _kbusget(bus):
    bus = str(bus)
    return kratebus[bus]

def _zakset(out, channels=None):
    out = str(out)
    if channels: chan = channels
    else: chan = _checkChannels()
    if out not in zakindex.keys():
        try:
            value = max(zakindex.values()) + chan
        except ValueError:
            value = chan
        zakindex[out] = value
        return value
    else:
        return zakindex[out]

def _zakget(out):
    out = str(out)
    return zakindex[out]

def _routeScoreline(line):
    if sequencer:
        _formatSeqScore(line)
    elif insideLoop:
        _processLoop(line)
    elif pythonInst:
        pythonlines[procNum][pythonInst].append(line)
    elif triggeredInst:
        triglines.append(line)
    else:
        scorelines.append(line)
 
def _setStringSet(name):
    if name in stringSetDict:
        return stringSetDict[name]
    else:
        stringSetDict[name] = len(stringSetDict)
        return stringSetDict[name]


##################################################
############# Algorithmic functions ##############
def chord(name='C', octave=6, format='midi'):
    """Transposes a chord name in a list of pitchs.
    
chord = 'C' # valid key in the chords dictionary
octave = 6
format = 'midi' # 'midi', 'hertz' or 'transpo'

return a list of notes

--- PARAMETERS ---

chord : A string pointing to a valid key in the chords dictionary.
octave : Transposition of the chord in number of octave.
format : Chord values format. Valid formats are 'midi', 'hertz' or 'transpo'. The midi pitch 60 is used as the central key for transposition format.
"""    
    midipitchs = [c+(12*(octave-1)) for c in chords[name]]

    if format == 'midi':
        return midipitchs
    elif format == 'hertz':    
        return [8.175798 * pow(1.0594633,pitch) for pitch in midipitchs]
    elif format == 'transpo':
        return [pow(1.059463, pitch - 60) for pitch in midipitchs]
    else:
        raise Error('Wrong chord format!')

def midiToHertz(pitch):
    """Converts a midi pitch to frequency.
    
pitch = midi_pitch

return frequency in hertz

--- PARAMETERS ---

pitch : midi pitch to be converted in Hertz (cycle per second)
"""
    return 8.175798 * pow(1.0594633, pitch)

def midiToTranspo(pitch, centralkey=60):
    """Converts a midi pitch to a transposition factor.
    
pitch = midi_pitch
centralkey = 60

return transpo value

--- PARAMETERS ---

pitch : midi pitch to be converted in transposition factor
centralkey : midi pitch used as nominal value (midiToTranspo(60) returns 1.)
"""

    return pow(1.059463, pitch - centralkey)    

def semitoneToTranspo(semitone):
    """Converts a semitone value to a transposition factor.
    
semitone = semitone_value

return transpo value

--- PARAMETERS ---

semitone : semitone value to be converted in transposition factor
"""
    return 2**(semitone/12.)

def scale(name='C', format='midi'):
    """Transposes a scale name in a list of pitchs.
    
scale = 'C' # valid key in the scales dictionary
format = 'midi' # 'midi', 'hertz' or 'transpo'

return a list of notes

--- PARAMETERS ---

chord : A string pointing to a valid key in the scales dictionary.
octave : Transposition of the chord in number of octave.
format : Scale values format. Valid formats are 'midi', 'hertz' or 'transpo'. The midi pitch 60 is used as the central key for transposition format.
"""    
    midipitchs = [scales[name][i%len(scales[name])]+(12*(i/len(scales[name]))) for i in range(int(128/(12./len(scales[name]))))]

    if format == 'midi':
        return midipitchs
    elif format == 'hertz':    
        return [8.175798 * pow(1.0594633,pitch) for pitch in midipitchs]
    elif format == 'transpo':
        return [pow(1.059463, pitch - 60) for pitch in midipitchs]
    else:
        raise Error('Wrong chord format!')        

# clean args list           
def pattern(time=.125, function=None, pattern=[1], *args):
    """Creates an independent clocker for scheduling events with sendEvent.
    
time = 0.125
function = function_to_be_called
pattern = [1]
arg1, ..., arg10 = up to 10 arguments can be passed to function

return a pattern objet

call start() method on the objet to start the thread

call play() to start clocker and play(False) to stop it

time is delay in seconds between each call.
pattern is a list of beat duration.

--- PARAMETERS ---

time : Delay time, in seconds, between each clock step.
function : Function to be called on each time of the pattern.
pattern : List of beat durations, in number of clock steps.
arg1 -> arg10 : Up to 10 arguments can be passed to function. These arguments are sent on each call.

--- METHODS ---

obj.start() : Clockers are managed in separated threads. This method must be called first to activate the threads.
obj.play() : Starts the clock.
obj.play(False) : Stops the clock.
obj.getTime() : Returns the current time, in seconds, since the start of the pattern.
obj.getBeat() : Returns the current beat of the pattern.
obj.getBar() : Return the current bar since the start of the pattern.
obj.changeTime(x) : Changes the time interval of the pattern objet.
obj.changePattern(list) : Assigns a new pattern to the pattern objet.
obj.stop() Kills the thread.
"""
    if type(pattern) != ListType: pattern = [pattern]
    if len(args) == 0:
        a = MyTimer(time, function, pattern)
    elif len(args) == 1:
        a = MyTimer(time, function, pattern, args[0])
    elif len(args) == 2:
        a = MyTimer(time, function, pattern, args[0], args[1])        
    elif len(args) == 3:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2])  
    elif len(args) == 4:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3])  
    elif len(args) == 5:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4])  
    elif len(args) == 6:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4], args[5])      
    elif len(args) == 7:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4], args[5], args[6])        
    elif len(args) == 8:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4], args[5], args[8], args[7])
    elif len(args) == 9:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8])
    elif len(args) == 10:
        a = MyTimer(time, function, pattern, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9])        
    patternDict[procNum].append(a)
    return a

def rhythmPattern(time=.125, function=None, size=16, weight1=90, weight2=60, weight3=20):
    """Creates an algorithmic rhythm pattern for scheduling events with sendEvent.
    
time = 0.125
function = function_to_be_called
size = 16
weight1 = 90
weight2 = 60
weight3 = 20

return pattern objet

call start() method on the objet to start thread

call play() to start timer and play(False) to stop it

time is delay in seconds between each call.

Function called will receive an amplitude value.

--- PARAMETERS ---

time : Delay time, in seconds, between each clock step.
function : Function to be called on each time of the pattern. Function will receive an amplitude value.
size : Length of the bar, in number of steps.
weight1 : Percentage chance of primary beats to be chosen.
weight2 : Percentage chance of secondary beats to be chosen.
weight3 : Percentage chance of weak beats to be chosen.

--- METHODS ---

obj.start() : Clockers are managed in separated threads. This method must be called first to activate the threads.
obj.play() : Starts the clock.
obj.play(False) : Stops the clock.
obj.getTime() : Returns the current time, in seconds, since the start of the pattern.
obj.getBeat() : Returns the current beat of the pattern.
obj.getBar() : Return the current bar since the start of the pattern.
obj.changeTime(x) : Changes the time interval of the pattern objet.
obj.changePattern(size, weigth1, weigth2, weigth3) : Regenerate a new algorithmic rhythm sequence based on new weights.
obj.stop() Kills the thread.
"""
    a = RhythmPattern(time, function, size, weight1, weight2, weight3)
    patternDict[procNum].append(a)
    return a

def drunk(mini=0, maxi=127):
    """Creates a drunk generator objet. Outputs integer values between mini and maxi.
    
mini = 0
maxi = 127 

return a drunk objet

--- PARAMETERS ---

mini : Minimum generated value.
maxi : Maximum generated value.

drunk performs a random walk generation.
"""
    return Drunk(mini, maxi)

def droneAndJump(mini=0, maxi=127):
    """Creates a droneAndJump generator objet. Outputs integer values between mini and maxi.
    
mini = 0
maxi = 127

return a droneAndJump objet

--- PARAMETERS ---

mini : Minimum generated value.
maxi : Maximum generated value.

droneAndJump outputs systematically a single note, but sometimes jumps to another note and returns to the first one.
"""
    return DroneAndJump(mini, maxi)

def repeater(mini=0, maxi=127):
    """Creates a repeater generator objet. Outputs integer values between mini and maxi.
    
mini = 0
maxi = 127

return a repeater objet

--- PARAMETERS ---

mini : Minimum generated value.
maxi : Maximum generated value.

repeater outputs many times a note before switching to another one.
"""
    return Repeater(mini, maxi)

def loopseg(mini=0, maxi=127):
    """Creates a loop segments generator objet. Outputs integer values between mini and maxi.
    
mini = 0
maxi = 127

return a loopseg objet

--- PARAMETERS ---

mini : Minimum generated value.
maxi : Maximum generated value.

loopseg generates cycle of notes and loop them a couple of times before switching.
"""
    return Loopseg(mini, maxi)

def markov(order=2):
    """Creates a markov chain generator objet.
    
order = 2 # 1 -> 10

return a markov objet

--- PARAMETERS ---

order : Order of the Markov chain. Determines how many past values will be used to build the probability table for the next note.
"""
    return Markov(order)
    
def mapper(input, inmin=0, inmax=127, outmin=0, outmax=1, log=False):
    """Maps input values inside inmin - inmax range according to output range outmin - outmax.
   
input = input_value
inmin = 0
inmax = 127
outmin = 0
outmax = 1
log = False

--- PARAMETERS ---

input : Incoming value (must be in the range inmin et inmax).
inmin : Minimum input value.
inmax : Maximum input value.
outmin : Minimum value of the resultant scale operation.
outmax : Maximum value of the resultant scale operation.
log : If True, scaling will be logarithmic.
"""    
    inrev = False
    outrev = False
    if inmin > inmax:
        inmin, inmax = inmax, inmin
        inrev = True
    if input < inmin: input = inmin
    if input > inmax: input = inmax
    inRange = float(inmax - inmin)
    if inrev: firstscale = (inmax - input) / inRange
    else: firstscale = (input - inmin) / inRange

    if log:
        firstscale = pow(firstscale,2)
        
    if outmin > outmax:
        outmin, outmax = outmax, outmin
        outrev = True
    outRange = float(outmax - outmin)

    if outrev: val = outmax - (firstscale * outRange)
    else: val = firstscale * outRange + outmin
    return val

def line(start=0, destination=1, duration=None):
    """Creates a line object.

start = 0
destination = 1 # can be a list to create a breakpoints line
duration = None # (in seconds) one value or a list (different durations for each destination)

call start() method on the objet to start the thread.

call play() to start the line and play(False) to stop it.

The method getValue() returns the current value of the line.

return a line object

--- PARAMETERS ---

start : Starting value of the line.
destination : Destination value. If a list is given, a breakpoints line will be created.
duration : Duration of a segment of the line. If only one value is supplied for a breakpoints line, each segment will have this duration. If a list is supplied, each destination will have it's own duration.

--- METHODS ---

obj.start() initializes the thread.
obj.play() starts the line.
obj.play(False) stops the line.
obj.getValue() returns the current value of the line.
obj.stop() kills the thread. 
"""
    if not duration: duration = GDUR
    a = Liner(start, destination, duration)
    patternDict[procNum].append(a)
    return a    

def oneCall(delay, function):
    """Calls a function after a delay time.

delay = delay_time_in_seconds
function = function_to_be_called

--- PARAMETERS ---

delay : Delay time, in seconds, before calling the function.
function : Function to be called.
"""
    a = OneCall(delay, function)
    a.start()
    del a

def logistic(constant=3.76, initial=0.1):
    """The logistic map equation is used to model population growth over time. 
This particular equation, though simple, provides a very rich set of behaviours for different values of 'constant' when iterated. 

constant = 3.76 # 0 -> 4
initial = 0.1 # 0 -> 1

return a logistic object.

--- PARAMETERS ---

constant : Constant value, in the range 0 to 4, used in the equation. When this value is between 0 and 1, result tends to 0. Between 1 and 3, it tends to stabilize on a middle point. Best behaviours are obtained in the range 3 to 4.
initial : Initial state, in the range 0 to 1, of the system. This value has an influence on all the sequence in output.

--- METHODS ---
obj.next() : return a new value.
obj.changeConstant(const) : Change the constant value used in the equation.
obj.changeInitial(x) : Reset the initial value used in the equation.
"""
    return Logistic(constant, initial)

def henon(a=1.4, b=0.3, x=0.1, y=0.1):
    """The Henon map is a discrete-time dynamical system. It is one of the most studied examples of dynamical systems that exhibit chaotic behavior. 
The Henon map takes a point (x, y) in the plane and maps it to a new point.

a = 1.4 # first constant
b = 0.3 # second constant
x = 0.1 # x initial value
y = 0.1 # y initial value

return a henon object.

--- PARAMETERS ---

a : Constant value, around 1.4, used in the equation.
b : Constant value, around 0.3, used in the equation.
x : X initial state, in the range 0 to 1, of the system.
y : Y initial state, in the range 0 to 1, of the system.

--- METHODS ---
obj.next() : return a tuple representing a new point (x, y).
obj.changeConstant((a,b)) : Change the constant values used in the equation. Values are a tuple (a, b)
obj.changeInitial((x,y)) : Reset the initial values used in the equation. Values are a tuple (x, y)
"""
    return Henon(a, b, x, y)


##################################################
############ Defining GEN functions ##############
def genAdsr(attack=0.01, decay=0.1, sustain=0.8, release=0.1, size=8192):
    """Defines an ADSR envelope. Returns table number.

attack = 0.01
decay = 0.1
sustain = 0.8 # 0 -> 1
release = 0.1
size = 8192 # must be a power-of-two

attack, decay, and release are fractional parts of the table size.

--- PARAMETERS ---

attack : Duration of attack phase.
decay : Duration of decay.
sustain : Amplitude for sustain phase.
release : Duration of release phase.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.

The envelope is in the range 0 to 1.

attack, decay, and release are fractional parts of the table size (where table size == 1). The length of the sustain is calculated from the unused part of table size.
"""
    global fnum
    att = int(size * attack)
    dec = int(size * decay)
    rel = int(size * release)
    bal = size - (att + dec + rel)
    sus = min(1., sustain)

    fnum += 1
    scorelines.append("f%ld 0 %d 7 0 %ld 1. %ld %f %ld %f %ld 0\n" % (fnum, size, att, dec, sus, bal, sus, rel))
    return fnum

def genLineseg(list=[0,10,1,10,0,10,1,10,0], size=8192):
    """Defines a breakpoints envelope. Returns table number.

list = [0,10,1,10,0,10,1,10,0]
size = 8192 # must be a power-of-two

list begins with the start value of the function and is followed by any pair (duration, value).
durations are rescaled to fit table size.

--- PARAMETERS ---

list : list begins with start value of the function and is followed by any pair (duration, value). Durations are rescaled to fit table size.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
"""

    global fnum
    totalsize = 0
    newlist = []
    for i in range(len(list)):
        if (i % 2) == 1:
            totalsize += list[i]

    for i in range(len(list)):
        if (i % 2) == 0: newlist.append(list[i])
        else: newlist.append(int(size * (list[i] / float(totalsize))))

    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(size) + " -7 " + " ".join([str(n) for n in newlist]) + '\n')
    return fnum

def genExpseg(list=[0.001,10,1,10,0.001,10,1,10,0.001], size=8192):
    """Defines an exponential breakpoints envelope. Returns table number.

list = [0.001,10,1,10,0.001,10,1,10,0.001]
size = 8192 # must be a power-of-two

list begins with the start value of the function and is followed by any pair (duration, value).
durations are rescaled to fit table size.

--- PARAMETERS ---

list : list begins with start value of the function and is followed by any pair (duration, value). Values must be non-zero. Durations are rescaled to fit table size.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
"""
    global fnum
    totalsize = 0
    newlist = []
    for i in range(len(list)):
        if (i % 2) == 1:
            totalsize += list[i]

    for i in range(len(list)):
        if (i % 2) == 0: newlist.append(list[i])
        else: newlist.append(int(size * (list[i] / float(totalsize))))

    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(size) + " -5 " + " ".join([str(n) for n in newlist]) + '\n')
    return fnum

def genWaveform(list=[1,0,0,.3,0,.2,0,0,.1], size=8192):
    """Defines a complex waveform to be read by a complex function. Returns table number.

list = [1,0,0,.3,0,.2,0,0,.1]
size = 8192 # must be a power-of-two

list is relative strengths of the fixed harmonic partial numbers.

--- PARAMETERS ---

list : Relative strengths of the fixed harmonic partial numbers 1,2,3, etc. Partials not required should be given a strength of zero.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
"""
    global fnum
    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(size) + " 10 " + " ".join([str(n) for n in list]) + '\n')
    return fnum

def genWindow(choice='hanning', size=8192):
    """Defines window function. Returns table number.

choice = 'hanning'
size = 8192 # must be a power-of-two

possible choices: 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian'

--- PARAMETERS ---

choice : Type of window to generate. Possible choices are 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian'.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.

The envelope is in the range 0 to 1.
"""
    global fnum
    list = [None, 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian']
    function = list.index(choice)
    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(size) + " 20 %d 1\n" % function)
    return fnum

def genSoundTable(sound, skiptime=0):
    """Loads a soundfile in a table. Returns table number.

sound = soundfile_name
skiptime = 0
"""
    global sndnum

    fullname = None
    if os.path.isfile(sound):
        fullname = sound
    elif project_paths:
        for path in project_paths:
            if os.path.isfile(os.path.join(path, sound)):
                fullname = os.path.join(path, sound)
                break
    if not fullname:
        fullname = os.path.join(sound_path, sound)

    infos = getSoundInfo(fullname)            
    chnls = infos[0]
    length = infos[4]
    tableFrac = infos[3]

    for i in range(24):
        size = math.pow(2,(i+1))
        if size > length:
            break

    nums = []
    for i in range(chnls):
        sndnum += 1
        nums.append(sndnum)
        scorelines.append("f" + str(sndnum) + " 0 " + str(int(size)) + " -1" + ' "' + fullname + '" ' + str(skiptime) + " 0 " + str(i+1) + "\n")
    
    return tuple(nums)

def genPulsarWave(sound):
    """Loads a waveform in a table. Returns table number.

sound = soundfile_name
"""
    global sndnum

    fullname = None
    if os.path.isfile(sound):
        fullname = sound
    elif project_paths:
        for path in project_paths:
            if os.path.isfile(os.path.join(path, sound)):
                fullname = os.path.join(path, sound)
                break
    if not fullname:
        fullname = os.path.join(sound_path, sound)

    infos = getSoundInfo(fullname)            
    chnls = infos[0]
    length = infos[4]
    tableFrac = infos[3]

    for i in range(24):
        size = math.pow(2,(i+1))
        if size > length:
            break

    sndnum += 1
    scorelines.append("f" + str(sndnum) + " 0 " + str(int(size)) + " 1" + ' "' + fullname + '" ' + " 0 0 1\n")
    
    return sndnum

def genDataTable(list):
    """Generates a table filled with a list of discrete values. Can be a list of sound name as strings. Returns table number.

list = list_of_values
"""
    global fnum

    for i in range(24):
        size = math.pow(2,(i+1))
        if size+1 == len(list):
            size += 1
            break
        elif size >= len(list):
            break

    if type(list[0]) == StringType:
        templist = []
        for i in range(len(list)):
            fullname = None
            if os.path.isfile(list[i]):
                fullname = list[i]
            elif project_paths:
                for path in project_paths:
                    if os.path.isfile(os.path.join(path, list[i])):
                        fullname = os.path.join(path, list[i])
                        break
            if not fullname:
                fullname = os.path.join(sound_path, list[i])
            
            fullname = _setStringSet(fullname)
            templist.append(fullname)
        list = templist    
            
    fnum += 1
    if not dataTableLen.has_key(procNum):
        dataTableLen[procNum] = {}
    dataTableLen[procNum][fnum] = size
    scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in list]) + '\n')
    return fnum

def genDiscreetTable(list):
    """Generates a table filled with a list of discrete values. The first position in the generated table will be the number of elements in the list. 
This table is intended to be used with discreetTableLoop function. Use this function with small list (< 100). For longer list,
use genDataFileTable function instead. Returns table number.

list = list_of_values
"""
    global fnum

    size = 65536
            
    fnum += 1
    if not dataTableLen.has_key(procNum):
        dataTableLen[procNum] = {}
    dataTableLen[procNum][fnum] = size
    scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + str(len(list)) + " " + " ".join([str(n) for n in list]) + '\n')
    return fnum

def genDataFileTable(list):
    """Writes data in a file and loads it in a table. The first position in the generated table will be the number of elements in the list. 
This table is intended to be used with discreetTableLoop function. Returns table number.

list = list_of_values
"""
    global fnum
    fnum += 1
 
    size = 65536

    f = open(temp_path + "/temp%d%d.txt" % (procNum, fnum), "w")
    f.write(str(len(list)) + " " + " ".join([str(i) for i in list]))
    f.close()
            
    if not dataTableLen.has_key(procNum):
        dataTableLen[procNum] = {}
    dataTableLen[procNum][fnum] = size
    scorelines.append("f" + str(fnum) + ' 0 ' + str(int(size)) + ' -23 "%s/temp%d%d.txt"\n' % (temp_path, procNum, fnum))
    
    return fnum

def tableMorphing(tablelist, indexVar=0, length=8192, starttime=0, duration=None):
    """Performs morphing between two or more discrete value tables. Returns table number.

tablelist = list of tables to use for morphing
indexVar = 0 # 0 -> 1
length = 8192 # waveform table length in samples
starttime = 0
duration = None
"""
    global fnum
    if not duration: duration = GDUR

    for i in range(24):
        size = math.pow(2,(i+1))
        if size >= len(tablelist):
            break

    for i in range(24):
        tsize = math.pow(2,(i+1))
        if tsize >= length:
            break

    if type(tablelist[0]) == TupleType:
        tablelist = [l[0] for l in tablelist]

    fnum += 1
    listnum = fnum
    padding = [tablelist[0] for i in range(int(size) - len(tablelist))]
    scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in tablelist]) + " " + " ".join([str(n) for n in padding]) + '\n')

    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(int(tsize)) + " -2 0\n")

    if midiSynthesizer:
        orchlines.append("ftmorf kbus%s*%s, %d, %d\n" % (str(indexVar), len(tablelist)-1, listnum, fnum))
        return fnum

    instrument = _checkInst('', 0, True)
    orchlines.append("instr %d\n" % instrument)
    _checkTrigged()
    orchlines.append('kind chnget "kbus%s"\n' % str(_kbusget(indexVar)))
    orchlines.append("ftmorf kind*%s, %d, %d\n" % (len(tablelist)-1, listnum, fnum))
    orchlines.append("endin\n\n")
    instrlist.append(instrument)

    line = "i%s %s %s\n" % (instrument, starttime, duration)
    _routeScoreline(line)
    return fnum

def genRhythmTable(size=16, weight1=90, weight2=60, weight3=20):
    """Generates a rhythm taps table for use with the sequencer. Returns table number.

size = 16 # number of beats per bar
weight1 = 90 # 0 -> 100
weight2 = 60 # 0 -> 100
weight3 = 20 # 0 -> 100
"""

    global fnum
    seq = [0 for i in range(size)]
    prob = [0 for i in range(size)]

    for i in range(24):
        tsize = math.pow(2,(i+1))
        if tsize >= size:
            break

    if size % 7 == 0:
        beat = 7
        for i in range(size):
            if i % beat == 4 or i % beat == 2:
                prob[i] = (weight2, .75)
            elif i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)
    elif size % 6 == 0:
        beat = 6
        for i in range(size):
            if i % beat == 3:
                prob[i] = (weight2, .75)
            elif i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)
    elif size % 5 == 0:
        beat = 5
        for i in range(size):
            if i % beat == 3:
                prob[i] = (weight2, .75)
            elif i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)
    elif size % 4 == 0:
        beat = 4
        for i in range(size):
            if i % beat == 2:
                prob[i] = (weight2, .75)
            elif i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)
    elif size % 3 == 0:
        beat = 3
        for i in range(size):
            if i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)
    elif size % 2 == 0:
        beat = 2
        for i in range(size):
            if i % beat == 0:
                prob[i] = (weight1, 1)
            else:
                prob[i] = (weight3, .5)

    for i in range(size):
        if random.randint(0, 100) < prob[i][0]:
            seq[i] = prob[i][1]
        else:
            seq[i] = 0

    fnum += 1
    scorelines.append("f" + str(fnum) + " 0 " + str(int(tsize)) + " -2 " + " ".join([str(n) for n in seq]) + '\n')
    return fnum
    
def recordBuffer(input, trigbus, bufferlength=1, starttime=0, duration=None):
    """Creates an empty buffer and record 'bufferlength' seconds of audio signal on trigger signal.
    
input = audio_input
trigbus = bus_trigger
bufferlength = 1
starttime = 0
duration = None

returns (table number, fractional part of table used)

* Can not be used inside midiSynth"""
    global sndnum
    if not duration: duration = GDUR

    if not 'recBuffer' in UDO:
        UDO.append('recBuffer')
        
    duration, starttime, input, trigbus, bufferlength = _convertToList(duration, starttime, input, trigbus, bufferlength)
    seq = max(len(trigbus), len(input), len(bufferlength), len(duration), len(starttime))

    if midiSynthesizer:
        raise Error("recordBuffer can't be used inside midiSynth")
        
    outlist = []
    for i in range(seq):    
        length = _wrap(bufferlength,i) * sr
        
        for p in range(24):
            size = math.pow(2,(p+1))
            if size > length:
                break
    
        tableFrac = length / size

        instrument = _checkInst('recordBuffer', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append('Strigkbus sprintf "kbus%d"')
        orchlines.append(", p4\n")
        orchlines.append("ktrig chnget Strigkbus\n")
        
        sndnums = []
        for k in range(_checkChannels()):
            sndnum += 1
            sndnums.append(sndnum)
            scorelines.append("f" + str(sndnum) + " 0 " + str(int(size)) + " -7 0 " + str(int(size)) + " 0\n")
            num = k + 1
            voice = _checkChannels() - num
            orchlines.append("ain%d zar p6-%d\n" % (num, voice))
            orchlines.append("recBuffer ain%d, ktrig, %d, p5\n" % (num, (sndnum)))
        orchlines.append("endin\n\n")
    
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'trigbus', 'bufferlength', 'input']
        
        ainput = _zakget(_wrap(input,i))
        line = 'i%s %s %s %s %s %s\n' % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _kbusget(_wrap(trigbus,i)), _wrap(bufferlength,i), str(ainput))
        _routeScoreline(line)
        outlist.append(tuple(sndnums))
        outlist.append(tableFrac)

    return tuple(outlist)

def reGenWaveform(table, list, size=8192, process=1):
    """Modifies an existing waveform ftable.

table = table_number    
list = list_of_harmonics_amplitude
size = 8192 # must be a power-of-two
process = 1 # process number, returned by startCsound
"""
    string = "f" + str(table) + " 0 " + str(size) + " 10 " + " ".join([str(n) for n in list]) + "\n"
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenDataTable(table, list, process=1):
    """Modifies an existing data ftable.

table = table_number    
list = list_of_values
process = 1 # process number, returned by startCsound
"""

    for i in range(24):
        size = math.pow(2,(i+1))
        if size+1 == len(list):
            size += 1
            break
        elif size >= len(list):
            break
            
    size = max(dataTableLen[process][table], size)
    dataTableLen[process][fnum] = size
    string = "f" + str(table) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in list]) + "\n"
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenDiscreetTable(table, list, process=1):
    """Modifies an existing discreet data ftable.

table = table_number    
list = list_of_values
process = 1 # process number, returned by startCsound
"""

    size = 65536

    size = max(dataTableLen[process][table], size)
    dataTableLen[process][table] = size
    string = "f" + str(table) + " 0 " + str(int(size)) + " -2 " + str(len(list)) + " " + " ".join([str(n) for n in list]) + "\n"
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenDataFileTable(table, list, process=1):
    """Modifies an existing data file ftable.

table = table_number    
list = list_of_values
process = 1 # process number, returned by startCsound
"""

    size = 65536

    f = open("%s/temp%d%d.txt" % (temp_path, procNum, table), "w")
    f.write(str(len(list)) + " " + " ".join([str(i) for i in list]))
    f.close()

    size = max(dataTableLen[process][table], size)
    dataTableLen[process][table] = size
    string = "f" + str(table) + ' 0 ' + str(int(size)) + ' -23 "%s/temp%d%d.txt"\n' % (temp_path, procNum, table)
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenSoundTable(table, sound, skiptime=0, process=1):
    """Modifies an existing soundfile table.

table = table_number
sound = soundfile_name
skiptime = 0
process = 1 # process number, returned by startCsound
"""

    fullname = None
    if os.path.isfile(sound):
        fullname = sound
    elif project_paths:
        for path in project_paths:
            if os.path.isfile(os.path.join(path, sound)):
                fullname = os.path.join(path, sound)
                break
    if not fullname:
        fullname = os.path.join(sound_path, sound)

    infos = getSoundInfo(fullname)            
    chnls = infos[0]
    length = infos[4]
    tableFrac = infos[3]

    for i in range(24):
        size = math.pow(2,(i+1))
        if size > length:
            break

    for i in range(chnls):
        string = "f" + str(table[i]) + " 0 " + str(int(size)) + " -1" + ' "' + fullname + '" ' + str(skiptime) + " 0 " + str(i+1) + "\n"
        port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)
    
def reGenWindow(table, choice='hanning', size=8192, process=1):
    """Modifies an existing window function table.

table = table_number
choice = 'hanning'
size = 8192 # must be a power-of-two
process = 1 # process number, returned by startCsound

possible choices: 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian'

--- PARAMETERS ---

table : Number returned by genWindow function specifying table to modify.
choice : Type of window to generate. Possible choices are 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian'.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
process : Ounk process number of the script, returned by startCsound.

The envelope is in the range 0 to 1.
"""
    list = [None, 'hamming', 'hanning', 'bartlett', 'blackman', 'blackman-harris', 'gaussian']
    function = list.index(choice)
    string = "f" + str(table) + " 0 " + str(size) + " 20 %d 1\n" % function
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenLineseg(table, list, size=8192, process=1):
    """Modifies an existing breakpoints envelope.

table = table_number
list = new_line_list
size = 8192 # must be a power-of-two
process = 1 # process number, returned by startCsound

list begins with the start value of the function and is followed by any pair (duration, value).
durations are rescaled to fit table size.

--- PARAMETERS ---

table : Number returned by genLineseg function specifying table to modify.
list : list begins with start value of the function and is followed by any pair (duration, value). Durations are rescaled to fit table size.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
process : Ounk process number of the script, returned by startCsound.
"""

    totalsize = 0
    newlist = []
    for i in range(len(list)):
        if (i % 2) == 1:
            totalsize += list[i]

    for i in range(len(list)):
        if (i % 2) == 0: newlist.append(list[i])
        else: newlist.append(int(size * (list[i] / float(totalsize))))

    string = "f" + str(table) + " 0 " + str(size) + " -7 " + " ".join([str(n) for n in newlist]) + '\n'
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenExpseg(table, list, size=8192, process=1):
    """Modifies an existing exponential breakpoints envelope.

table = table_number
list = new_line_list
size = 8192 # must be a power-of-two
process = 1 # process number, returned by startCsound

list begins with the start value of the function and is followed by any pair (duration, value).
durations are rescaled to fit table size.

--- PARAMETERS ---

table : Number returned by genExpseg function specifying table to modify.
list : list begins with start value of the function and is followed by any pair (duration, value). Values must be non-zero. Durations are rescaled to fit table size.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
process : Ounk process number of the script, returned by startCsound.
"""
    totalsize = 0
    newlist = []
    for i in range(len(list)):
        if (i % 2) == 1:
            totalsize += list[i]

    for i in range(len(list)):
        if (i % 2) == 0: newlist.append(list[i])
        else: newlist.append(int(size * (list[i] / float(totalsize))))

    string = "f" + str(table) + " 0 " + str(size) + " -5 " + " ".join([str(n) for n in newlist]) + '\n'
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def reGenAdsr(table, attack=0.01, decay=0.1, sustain=0.8, release=0.1, size=8192, process=1):
    """Modifies an existing ADSR envelope table.

table = table_number
attack = 0.01
decay = 0.1
sustain = 0.8 # 0 -> 1
release = 0.1
size = 8192 # must be a power-of-two
process = 1 # process number, returned by startCsound

attack, decay, and release are fractional parts of the table size.

--- PARAMETERS ---

table : Number returned by genAdsr function specifying table to modify.
attack : Duration of attack phase.
decay : Duration of decay.
sustain : Amplitude for sustain phase.
release : Duration of release phase.
size : Number of points in the table. Ordinarily a power of 2 or a power-of-2 plus 1. The maximum tablesize is 16777216 (2^24) points.
process : Ounk process number of the script, returned by startCsound.

The envelope is in the range 0 to 1.

attack, decay, and release are fractional parts of the table size (where table size == 1). The length of the sustain is calculated from the unused part of table size.
"""
    att = int(size * attack)
    dec = int(size * decay)
    rel = int(size * release)
    bal = size - (att + dec + rel)
    sus = min(1., sustain)

    string = "f%ld 0 %d 7 0 %ld 1. %ld %f %ld %f %ld 0\n" % (table, size, att, dec, sus, bal, sus, rel)
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)


####################################################
########### Midi Synthesizer functions  ############
def readMidiFile(file):
    """Reads a midi file.

file = midi_file_name"""
    global midifile
    temp_file = None
    if os.path.isfile(file):
        temp_file = file
    elif project_paths:
        for path in project_paths:
            if os.path.isfile(os.path.join(path, file)):
                temp_file = os.path.join(path, file)
                break
    if not temp_file:            
        temp_file = os.path.join(midi_path, file)
    midifile = '-F ' + temp_file

def beginMidiSynth(channel=1, centralkey=60, release=1, pitchbend=2, skipampscaling=False):
    """Begins the definition of a MIDI instrument.

channel = 1 # MIDI channel
centralkey = 60 # MIDI pitch
release = 1 # seconds
pitchbend = 2 # semi-tones
skipampscaling = False # if True velocity doesn't change amplitude values
"""
    global midiSynthesizer, midiSynthesizerSwitch, midi, midiRelease
    midiSynthesizer = True
    midi = '-M%d ' % mididev
    midiSynthesizerChannel.append(channel)
    midiRelease = release

    orchlines.append("instr %d\n" % channel)
    orchlines.append("kcps cpsmidib %d\n" % pitchbend)
    orchlines.append("kbasecps pow 1.0594633, %s\n" % centralkey)
    orchlines.append("kbasecps = kbasecps * 8.175798\nkpit = kcps / kbasecps\n")
    if not skipampscaling:
        orchlines.append("iamp ampmidi 1\n")
        orchlines.append("irealamp = iamp\n")
    else:
        orchlines.append("iamp = 1\n")
        orchlines.append("irealamp ampmidi 1\n")
    #orchlines.append("kaft aftouch .707, 1.5\n")
    orchlines.append("kvo ctrl7 1, 7, 0, 1\n")
    orchlines.append("kvol port kvo, .02\n")
    orchlines.append("xtratim %s\n" % release)
    orchlines.append("krel init 0\nkrel release\n")
    orchlines.append("if (krel == 1) kgoto rel\n")
    orchlines.append("kamp1 linseg 0, .002, 1, 50, 1\n")
    orchlines.append("kamp = kamp1 * kvol * iamp\nkgoto done\n")
    orchlines.append("rel:\nkamp2 linseg 1, %s, 0\n" % release)
    orchlines.append("kamp = kamp1*kamp2*kvol*iamp\ndone:\n")

def endMidiSynth(out='dac'):
    """Closes the definition of a MIDI instrument.

out = 'dac'"""
    global midiSynthesizer, keyboardSplit, velocitySplit
    midiSynthesizer = False

    if velocitySplit:
        orchlines.append("endif\n")
        velocitySplit = False
    if keyboardSplit:
        orchlines.append("endif\n")
        keyboardSplit = False
    if out == 'dac':
        for j in range(_checkChannels()):
            orchlines.append("gaout%s = gaout%s + (" % (j, j))
            for i in midiInstOutAudio[:-1]:
                orchlines.append("gamidiout%s%d+" % (j, i))
            orchlines.append("gamidiout%s%d)*kamp\n" % (j, midiInstOutAudio[-1]))
    else:
        out = _zakset(out)
        for j in range(_checkChannels()):
            voice = (_checkChannels()-1) - j
            orchlines.append("zawm (")
            for i in midiInstOutAudio[:-1]:
                orchlines.append("gamidiout%s%d+" % (j, i))
            orchlines.append("gamidiout%s%d)*kamp, %s\n" % (j, midiInstOutAudio[-1], str(out - voice)))
    for i in midiInstBusAudio:
        for j in range(_checkChannels()):
            orchlines.append("abus%s%s = 0\n" % (j, i))
    for i in midiInstOutAudio:
        for j in range(_checkChannels()):
            orchlines.append("gamidiout%s%d = 0\n" % (j, i))
    orchlines.append("endin\n\n")

class MidiSynth:
    """Begins the definition of a MIDI instrument.

channel = 1 # MIDI channel
centralkey = 60 # MIDI pitch
release = 1 # seconds
pitchbend = 2 # semi-tones
skipampscaling = False # if True velocity doesn't change amplitude values
out = 'dac'
"""
    def __init__(self, channel=1, centralkey=60, release=1, pitchbend=2, skipampscaling=False, out='dac'):
        global midiSynthesizer, midiSynthesizerSwitch, midi, midiRelease
        midiSynthesizer = True
        midi = '-M%d ' % mididev
        midiSynthesizerChannel.append(channel)
        midiRelease = release

        orchlines.append("instr %d\n" % channel)
        orchlines.append("kcps cpsmidib %d\n" % pitchbend)
        orchlines.append("kbasecps pow 1.0594633, %s\n" % centralkey)
        orchlines.append("kbasecps = kbasecps * 8.175798\nkpit = kcps / kbasecps\n")
        if not skipampscaling:
            orchlines.append("iamp ampmidi 1\n")
            orchlines.append("irealamp = iamp\n")
        else:
            orchlines.append("iamp = 1\n")
            orchlines.append("irealamp ampmidi 1\n")
        #orchlines.append("kaft aftouch .707, 1.5\n")
        orchlines.append("kvo ctrl7 1, 7, 0, 1\n")
        orchlines.append("kvol port kvo, .02\n")
        orchlines.append("xtratim %s\n" % release)
        orchlines.append("krel init 0\nkrel release\n")
        orchlines.append("if (krel == 1) kgoto rel\n")
        orchlines.append("kamp1 linseg 0, .002, 1, 50, 1\n")
        orchlines.append("kamp = kamp1 * kvol * iamp\nkgoto done\n")
        orchlines.append("rel:\nkamp2 linseg 1, %s, 0\n" % release)
        orchlines.append("kamp = kamp1*kamp2*kvol*iamp\ndone:\n")
        self.out = out

    def __enter__(self):
        pass

    def __exit__(self, type, value, traceback):
        global midiSynthesizer, keyboardSplit, velocitySplit
        midiSynthesizer = False

        if velocitySplit:
            orchlines.append("endif\n")
            velocitySplit = False
        if keyboardSplit:
            orchlines.append("endif\n")
            keyboardSplit = False
        if self.out == 'dac':
            for j in range(_checkChannels()):
                orchlines.append("gaout%s = gaout%s + (" % (j, j))
                for i in midiInstOutAudio[:-1]:
                    orchlines.append("gamidiout%s%d+" % (j, i))
                orchlines.append("gamidiout%s%d)*kamp\n" % (j, midiInstOutAudio[-1]))
        else:
            out = _zakset(self.out)
            for j in range(_checkChannels()):
                voice = (_checkChannels()-1) - j
                orchlines.append("zawm (")
                for i in midiInstOutAudio[:-1]:
                    orchlines.append("gamidiout%s%d+" % (j, i))
                orchlines.append("gamidiout%s%d)*kamp, %s\n" % (j, midiInstOutAudio[-1], str(out - voice)))
        for i in midiInstBusAudio:
            for j in range(_checkChannels()):
                orchlines.append("abus%s%s = 0\n" % (j, i))
        for i in midiInstOutAudio:
            for j in range(_checkChannels()):
                orchlines.append("gamidiout%s%d = 0\n" % (j, i))
        orchlines.append("endin\n\n")

def splitKeyboard(firstnote=0, endnote=127, centralkey=48, pitchbend=2):
    """Defines a keyboard region in a MIDI instrument.

firstnote = 0
endnote = 127
centralkey = 48
pitchbend = 2 # semi-tones
"""
    global keyboardSplit, velocitySplit

    if velocitySplit:
        orchlines.append("endif\n")
        velocitySplit = False

    if keyboardSplit:
        orchlines.append("elseif inote >= %d && inote <= %d then\n" % (firstnote, endnote))
    else:
        orchlines.append("inote notnum\n")
        orchlines.append("if inote >= %d && inote <= %d then\n" % (firstnote, endnote))
    orchlines.append("kcps cpsmidib %d\n" % pitchbend)
    orchlines.append("kbasecps pow 1.0594633, %s\n" % centralkey)
    orchlines.append("kbasecps = kbasecps * 8.175798\nkpit = kcps / kbasecps\n")
    keyboardSplit = True

def splitVelocity(minthresh=0, maxthresh=1):
    """Defines a velocity region in a MIDI instrument.
    
minthresh = 0
maxthresh = 1"""
    global velocitySplit
    if velocitySplit:
        orchlines.append("elseif irealamp > %s && irealamp <= %s then\n" % (minthresh, maxthresh))
    else:
        orchlines.append("if irealamp > %s && irealamp <= %s then\n" % (minthresh, maxthresh))
    velocitySplit = True

def midiSynthGetBus(bus, input):
    """Retrieves an external controller to use in a MIDI instrument.

bus = name_of_the_MIDI_instrument_bus
input = name_of_the_external_bus"""
    bus, input = _convertToList(bus, input)
    seq = max(len(bus), len(input))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append('kbus%s chnget "kbus%s"\n' % (str(_wrap(bus,i)), str(_kbusget(_wrap(input,i)))))
        return

def midiSynthCtl(bus, ctlnumber=1, minscale=0, maxscale=127, portamento=.02):
    """Takes a midi controller as input and sends it on a controller bus.

bus = bus_output
ctlnumber = 1
minscale = 0
maxscale = 127
portamento = 0.02 # seconds
"""
    bus, ctlnumber, minscale, maxscale, portamento = _convertToList(bus, ctlnumber, minscale, maxscale, portamento)
    seq = max(len(bus), len(ctlnumber), len(minscale), len(maxscale), len(portamento))

    if midiSynthesizer:
        for i in range(seq):    
            orchlines.append("kctl%d midictrl %s, %s, %s\n" % (i, _wrap(ctlnumber,i), _wrap(minscale,i), _wrap(maxscale,i)))
            orchlines.append("kbus%s port kctl%d, %s\n" % (_wrap(bus,i), i, _wrap(portamento,i)))
        return

        
####################################################
############### Sequencer functions  ###############
def beginSequencer(input, table, active=1, trigbus=None, trigval=None, mode=0, clockdelay=0, clockdelayVar=None):
    """Begins the definition of a sequencer.

input = metro_input
table = amplitude_tap_table # generated with genDataTable or genRhythmTable
active = 1 # on / off
trigbus = None # controller bus
trigval = None # a value on controller bus to start and stop the sequencer
mode = 0
clockdelay = 0
clockdelayVar = None

If table are list of tables:
    if mode == 0: tables are read sequentially
    elif mode > 0: table are choosen randomly from tables in the list.
mode is the chance (%) to choose a new table
"""
    global sequencer, seqInstrument, seqParamsTable
    if type(table) != ListType: table = [table]

    seqParamsTable = []
    sequencer = True
    instrument = _checkInst('', 0, True)
    seqInstrument = instrument
    seqlines.append("instr %d\n" % instrument)
    seqlines.append("kon init %d\n" % active)
    seqlines.append("krythmtable init %d\n" % table[0])
    seqlines.append('ktap chnget "kbus%s"\n' % str(_kbusget(input)))
    if clockdelay > 0:
        if clockdelayVar:
            seqlines.append('kclockvar chnget "kbus%s"\n' % str(_kbusget(clockdelayVar)))
            seqlines.append("ktap vdel_k ktap, %s*kclockvar, 1\n" % clockdelay)
        else:
            seqlines.append("ktap delayk ktap, %s\n" % clockdelay)
    seqlines.append("kchanged changed ktap\n")
    if trigval:
        seqlines.append("kswitch init -1\n")
        seqlines.append('kswitch chnget "kbus%s"\n' % str(_kbusget(trigbus)))
        seqlines.append("kswichanged changed kswitch\n")
        seqlines.append("if kswichanged == 1 && kswitch == %d then\n" % trigval)
        seqlines.append("if kon == 0 then\n")
        seqlines.append("kon = 1\n")
        seqlines.append("else\n")
        seqlines.append("kon = 0\n")
        seqlines.append("kswitch = -1\n")
        seqlines.append("endif\nendif\n")
    seqlines.append("if kchanged == 1 && kon == 1 then\n")
    if len(table) > 1:
        global fnum
        for i in range(24):
            size = math.pow(2,(i+1))
            if size >= len(table):
                break
        fnum += 1
        scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in table]) + '\n')
        seqlines.append("if (ktap-1) == 0 then\n")
        seqlines.append("kchoose init %d\n" % (len(table)-1))
        if mode != 0:
            seqlines.append("krandom random 0,100\n")
            seqlines.append("if int(krandom) < %s then\n" % mode)
            seqlines.append("kchoose random 0, %d\n" % len(table))
            seqlines.append("krythmtable table int(kchoose), %d\n" % fnum)
            seqlines.append("endif\nendif\n")
        else:
            seqlines.append("kchoose = (kchoose+1) %")
            seqlines.append(" %d\n" % len(table))
            seqlines.append("krythmtable table int(kchoose), %d\n" % fnum)
            seqlines.append("endif\n")
    seqlines.append("kcheck tablekt ktap-1, krythmtable, 0, 0, 1\n")
    seqlines.append("if kcheck != 0 then\n")
    seqlines.append("kamp = kcheck\n")

def endSequencer(starttime=0, duration=None):
    """Closes the definition of a sequencer.

starttime = 0
duration = None
"""
    global sequencer, seqlines, seqPitchTable, seqParamsTable
    sequencer = False
    seqParamsTable = []

    if not duration: duration = GDUR
    instrument = seqInstrument

    for line in seqlines:
        orchlines.append(line)
    orchlines.append("endif\nendif\nendin\n\n")

    scorelines.append("i%s %s %s\n" % (instrument, starttime, duration))

    seqlines = []
    seqPitchTable = None

class Sequencer:
    """Begins the definition of a sequencer.

input = metro_input
table = amplitude_tap_table # generated with genDataTable or genRhythmTable
active = 1 # on / off
trigbus = None # controller bus
trigval = None # a value on controller bus to start and stop the sequencer
mode = 0
clockdelay = 0
clockdelayVar = None
starttime = 0
duration = None

If table are list of tables:
    if mode == 0: tables are read sequentially
    elif mode > 0: table are choosen randomly from tables in the list.
mode is the chance (%) to choose a new table
"""

    def __init__(self, input, table, active=1, trigbus=None, trigval=None, mode=0, 
                 clockdelay=0, clockdelayVar=None, starttime=0, duration=None):
        global sequencer, seqInstrument, seqParamsTable
        if type(table) != ListType: table = [table]

        seqParamsTable = []
        sequencer = True
        instrument = _checkInst('', 0, True)
        seqInstrument = instrument
        seqlines.append("instr %d\n" % instrument)
        seqlines.append("kon init %d\n" % active)
        seqlines.append("krythmtable init %d\n" % table[0])
        seqlines.append('ktap chnget "kbus%s"\n' % str(_kbusget(input)))
        if clockdelay > 0:
            if clockdelayVar:
                seqlines.append('kclockvar chnget "kbus%s"\n' % str(_kbusget(clockdelayVar)))
                seqlines.append("ktap vdel_k ktap, %s*kclockvar, 1\n" % clockdelay)
            else:
                seqlines.append("ktap delayk ktap, %s\n" % clockdelay)
        seqlines.append("kchanged changed ktap\n")
        if trigval:
            seqlines.append("kswitch init -1\n")
            seqlines.append('kswitch chnget "kbus%s"\n' % str(_kbusget(trigbus)))
            seqlines.append("kswichanged changed kswitch\n")
            seqlines.append("if kswichanged == 1 && kswitch == %d then\n" % trigval)
            seqlines.append("if kon == 0 then\n")
            seqlines.append("kon = 1\n")
            seqlines.append("else\n")
            seqlines.append("kon = 0\n")
            seqlines.append("kswitch = -1\n")
            seqlines.append("endif\nendif\n")
        seqlines.append("if kchanged == 1 && kon == 1 then\n")
        if len(table) > 1:
            global fnum
            for i in range(24):
                size = math.pow(2,(i+1))
                if size >= len(table):
                    break
            fnum += 1
            scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in table]) + '\n')
            seqlines.append("if (ktap-1) == 0 then\n")
            seqlines.append("kchoose init %d\n" % (len(table)-1))
            if mode != 0:
                seqlines.append("krandom random 0,100\n")
                seqlines.append("if int(krandom) < %s then\n" % mode)
                seqlines.append("kchoose random 0, %d\n" % len(table))
                seqlines.append("krythmtable table int(kchoose), %d\n" % fnum)
                seqlines.append("endif\nendif\n")
            else:
                seqlines.append("kchoose = (kchoose+1) %")
                seqlines.append(" %d\n" % len(table))
                seqlines.append("krythmtable table int(kchoose), %d\n" % fnum)
                seqlines.append("endif\n")
        seqlines.append("kcheck tablekt ktap-1, krythmtable, 0, 0, 1\n")
        seqlines.append("if kcheck != 0 then\n")
        seqlines.append("kamp = kcheck\n")
    
        self.starttime = starttime
        self.duration = duration

    def __enter__(self):
        pass

    def __exit__(self, type, value, traceback):
        global sequencer, seqlines, seqPitchTable, seqParamsTable
        sequencer = False
        seqParamsTable = []

        if not self.duration: self.duration = GDUR
        instrument = seqInstrument

        for line in seqlines:
            orchlines.append(line)
        orchlines.append("endif\nendif\nendin\n\n")

        scorelines.append("i%s %s %s\n" % (instrument, self.starttime, self.duration))

        seqlines = []
        seqPitchTable = None

def sequencerPitchTable(table):
    """Specifies a pitch multiplicator table.

table = data_table"""
    global seqPitchTable
    seqPitchTable = table
    seqlines.append("kpit table ktap-1, %d, 0, 0, 1\n" % table)

def seqParameterTable(parameter, table):
    """Specifies a parameter table and replaces existing value.

parameter = parameter_name
table = data_table"""
    global seqParamsTable
    parameter, table = _convertToList(parameter, table)
    seq = max(len(parameter), len(table))

    for i in range(seq):    
        seqParamsTable.append(_wrap(parameter,i))
        seqlines.append("k%s table ktap-1, %d, 0, 0, 1\n" % (_wrap(parameter,i), _wrap(table,i)))

def _formatSeqScore(line):
    global seqParamsTable
    list = line.split()
    list[0] = list[0][1:]
    seqlines.append('event "i", ')

    val = eval(list[0])
    if type(val) == FloatType:
        val = str(int(math.floor(val)))
    elif type(val) == IntType:
        val = str(val)

    if seqPitchTable:
        if paramDict[procNum].has_key(val):
            if 'pitch' in paramDict[procNum][val]:
                pos = paramDict[procNum][val].index('pitch') + 1
                list[pos] = str(list[pos]) + '*kpit'

    if paramDict[procNum].has_key(val):
        if 'amplitude' in paramDict[procNum][val]:
            pos = paramDict[procNum][val].index('amplitude') + 1
            list[pos] = str(list[pos]) + '*kamp'

    for para in seqParamsTable:
        if paramDict[procNum].has_key(val):
            if para in paramDict[procNum][val]:
                pos = paramDict[procNum][val].index(para) + 1
                list[pos] = 'k%s' % para

    for i in range(len(list)-1):
        seqlines.append("%s, " % list[i])
    seqlines.append("%s\n" % list[-1])


####################################################
########## Trigger instrument functions  ###########
def beginTrigInst(trigbus=None, trigval=None, release=None):
    """Begins the definition of a triggered instrument.

trigbus = None # controller bus
trigval = None # a value on controller bus to start and stop the instrument
release = None # fade out time in sec.
"""
    global triggeredInst, trigInstrument, trigRelease
    
    trigRelease = release
    triggeredInst = True
    instrument = _checkInst('', 0, True)
    trigInstrument = instrument
    trigheadlines.append("instr %d\n" % instrument)
    trigheadlines.append("kon init 0\n")
    trigheadlines.append("kswitch init -1\n")
    trigheadlines.append('kswitch chnget "kbus%s"\n' % str(_kbusget(trigbus)))
    trigheadlines.append("kswichanged changed kswitch\n")
    trigheadlines.append("if kswichanged == 1 && kswitch == %d then\n" % trigval)
    trigheadlines.append("if kon == 0 then\n")
    trigheadlines.append("kon = 1\n")
    trigheadlines.append("else\n")
    trigheadlines.append("kon = 0\n")
    trigheadlines.append("kswitch = -1\n")
    trigheadlines.append("endif\n")

def endTrigInst(starttime=0, duration=None):
    """Closes the definition of a triggered instrument.

starttime = 0
duration = None
"""
    global triggeredInst, triglines, trigheadlines, trigRelease
    triggeredInst = False

    if not duration: duration = GDUR
    instrument = trigInstrument

    trigInstUsed = []

    for line in trigheadlines:
        orchlines.append(line)
    orchlines.append("if kon == 1 then\n")
    orchlines.append('scoreline {{ \n')
    for line in triglines:
        list = line.split()
        trigInstUsed.append(list[0][1:])
        orchlines.append(line)
    orchlines.append(' }}, 1\n')    
    orchlines.append("elseif kon == 0 then\n")
    for inst in trigInstUsed:
        orchlines.append("turnoff2 %s, 4, %s\n" % (inst, trigRelease))
    orchlines.append("endif\nendif\n")    
    orchlines.append("endin\n\n")

    scorelines.append("i%s %s %s\n" % (instrument, starttime, duration))

    trigheadlines = []
    triglines = []
    trigRelease = None

class TrigInst:
    """Begins the definition of a triggered instrument.

trigbus = None # controller bus
trigval = None # a value on controller bus to start and stop the instrument
release = None # fade out time in sec.
starttime = 0
duration = None
"""
    def __init__(self, trigbus=None, trigval=None, release=None, starttime=0, duration=None):
        global triggeredInst, trigInstrument, trigRelease
        
        trigRelease = release
        triggeredInst = True
        instrument = _checkInst('', 0, True)
        trigInstrument = instrument
        trigheadlines.append("instr %d\n" % instrument)
        trigheadlines.append("kon init 0\n")
        trigheadlines.append("kswitch init -1\n")
        trigheadlines.append('kswitch chnget "kbus%s"\n' % str(_kbusget(trigbus)))
        trigheadlines.append("kswichanged changed kswitch\n")
        trigheadlines.append("if kswichanged == 1 && kswitch == %d then\n" % trigval)
        trigheadlines.append("if kon == 0 then\n")
        trigheadlines.append("kon = 1\n")
        trigheadlines.append("else\n")
        trigheadlines.append("kon = 0\n")
        trigheadlines.append("kswitch = -1\n")
        trigheadlines.append("endif\n")
        self.starttime = starttime
        self.duration = duration

    def __enter__(self):
        pass

    def __exit__(self, type, value, traceback):
        global triggeredInst, triglines, trigheadlines, trigRelease
        triggeredInst = False
    
        if not self.duration: self.duration = GDUR
        instrument = trigInstrument
    
        trigInstUsed = []
    
        for line in trigheadlines:
            orchlines.append(line)
        orchlines.append("if kon == 1 then\n")
        orchlines.append('scoreline {{ \n')
        for line in triglines:
            list = line.split()
            trigInstUsed.append(list[0][1:])
            orchlines.append(line)
        orchlines.append(' }}, 1\n')    
        orchlines.append("elseif kon == 0 then\n")
        for inst in trigInstUsed:
            orchlines.append("turnoff2 %s, 4, %s\n" % (inst, trigRelease))
        orchlines.append("endif\nendif\n")    
        orchlines.append("endin\n\n")
    
        scorelines.append("i%s %s %s\n" % (instrument, self.starttime, self.duration))
    
        trigheadlines = []
        triglines = []
        trigRelease = None


####################################################
################# Loop functions  ##################
def beginLoop(starttime=0, duration=None, legato=None, amplitude=None):
    """Starts the definition of a looping section.
    
starttime = 0
duration = None
legato = None
amplitude = None

legato and amplitude are single value or [start_value, end_value]. These values are used to multiply
duration and amplitude of functions inside the loop. If it is a list [start_value, end_value], interpolation
are done across the length of the loop
"""
    global insideLoop, loopStart, loopDur, loopLegato, loopAmplitude
    insideLoop = True
    loopStart = starttime
    loopDur = duration
    loopLegato = legato
    loopAmplitude = amplitude

def endLoop():
    """Closes the loop section."""
    global insideLoop
    insideLoop = False
    
def _processLoop(line):
    global loopStart, loopDur, loopLegato, loopAmplitude
    if not loopDur: loopDur = GDUR
    if not loopLegato: loopLegato = 1
    if not loopAmplitude: loopAmplitude = 1
    
    sep = line.split()
    dur = float(sep[2])
    howmany = int(loopDur / dur)
    
    if type(loopLegato) in [FloatType, IntType]:
        legatoList = [loopLegato for i in range(howmany)]
    else:
        legRange = loopLegato[1] - loopLegato[0]
        legStep = float(legRange) / howmany
        legatoList = [legStep*i+loopLegato[0] for i in range(howmany)]

    val = eval(sep[0][1:])
    if type(val) == FloatType:
        val = str(int(math.floor(val)))
    elif type(val) == IntType:
        val = str(val) 

    if paramDict[procNum].has_key(val):
        if 'amplitude' in paramDict[procNum][val]:
            pos = paramDict[procNum][val].index('amplitude') + 1
            firstamp = float(sep[pos])
    
    if type(loopAmplitude) in [FloatType, IntType]:
        loopAmplitude = [loopAmplitude for i in range(howmany)]
    else:
        ampRange = max(loopAmplitude) - min(loopAmplitude)
        ampStep = float(ampRange) / howmany
        if loopAmplitude[0] < loopAmplitude[1]:
            loopAmplitude = [ampStep*i+min(loopAmplitude) for i in range(howmany)]
        else:
            loopAmplitude = [ampStep*(howmany-(i+1))+min(loopAmplitude) for i in range(howmany)]
        
    for i in range(howmany):
        start = dur * i + loopStart
        sep[1] = str(start)
        sep[2] = str(dur * legatoList[i])
        if paramDict[procNum].has_key(val):
            if 'amplitude' in paramDict[procNum][val]:
                pos = paramDict[procNum][val].index('amplitude') + 1
                sep[pos] = str(firstamp * math.sqrt(loopAmplitude[i]))
        realLine = " ".join([s for s in sep])
        scorelines.append(realLine + '\n')

class Loop:
    def __init__(self, starttime=0, duration=None, legato=None, amplitude=None): 
        """Starts the definition of a looping section.
    
starttime = 0
duration = None
legato = None
amplitude = None

legato and amplitude are single value or [start_value, end_value]. These values are used to multiply
duration and amplitude of functions inside the loop. If it is a list [start_value, end_value], interpolation
are done across the length of the loop
"""
        global loopStart, loopDur, loopLegato, loopAmplitude
        loopStart = starttime
        loopDur = duration
        loopLegato = legato
        loopAmplitude = amplitude

    def __enter__(self):

        global insideLoop
        insideLoop = True

    def __exit__(self, type, value, traceback):
        """Closes the loop section."""
        global insideLoop
        insideLoop = False
    
####################################################
########## Python instrument functions  ############
def beginPythonInst(voice=1):
    """Begins the definition of a Python instrument.
    
voice = 1 # voice number to separate multiple Python instruments

This instrument are set to receive events from Python with sendEvent function

--- PARAMETERS ---

voice : The number of the instrument as an arbitrary number. This value can be used to send events to this particular instrument with sendEvent function.
"""
    global pythonInst
    pythonInst = str(voice)
    pythonlines[procNum][pythonInst] = []
        
def endPythonInst():
    """Closes the python instrument section.
    
--- PARAMETERS ---

No parameter. This function closes the definition of a Python instrument.
    """
    global pythonInst
    pythonInst = False
 
class PythonInst:
    def __init__(self, voice=1):  
        """Begins the definition of a Python instrument.
    
voice = 1 # voice number to separate multiple Python instruments

This instrument are set to receive events from Python with sendEvent function

--- PARAMETERS ---

voice : The number of the instrument as an arbitrary number. This value can be used to send events to this particular instrument with sendEvent function.
"""
        global pythonInst
        pythonInst = str(voice)
        pythonlines[procNum][pythonInst] = []

    def __enter__(self):
        pass

    def __exit__(self, type, value, traceback):
        """Closes the python instrument section.
    
--- PARAMETERS ---

No parameter. This function closes the definition of a Python instrument.
    """
        global pythonInst
        pythonInst = False 

def sendEvent(voice=1, dict=None, process=1, post=False):
    """Sends an event to a python instrument.
    
voice = number_of_the_instrument
dict = Dictionary of parameters to modify
process = 1 # process number
post = False # if True, commands are printed to the console

dict['function_name']['parameter_name'] = x

--- PARAMETERS ---

voice : Voice number of the Python instrument intended to receive the event.
dict : A dictionary specifying new parameter values for an event. If a parameter is given in the Python instrument and is not given in the dictionary, the value in the Python instrument will be used.
process : Ounk process number, returned by startCsound. This is used to avoid interference between different Python instrument inside different already running scripts.

- Dictionary syntax -

The keys are function names (as a string) associated with a dictionary of parameters. Parameters are keys (also as a string) associated with the desired value.
To control a Python instrument with a sound player and a lowpass filter, dict should look like this:

dict = \{\}
dict['playSound'] = \{\}
dict['lowpass'] = \{\}
dict['playSound']['pitch'] = .5
dict['playSound']['loop'] = True
dict['lowpass']['cutoff'] = 2500

sendEvent(voice=1, dict=dict, process=1)
"""
    counter = []
    if processDict.has_key(process):
        #print pythonlines[process][str(voice)]
        #print instrumentDict[process]
        for line in pythonlines[process][str(voice)]:
            list = line.split()
            inst = list[0][1:]
            list[0] = list[0][1:]
    
            val = eval(inst)
            if type(val) == FloatType:
                val = str(int(math.floor(val)))
            elif type(val) == IntType:
                val = str(val)  
    
            counter.append(val)
            for p in dict.keys():
                if int(val) in instrumentDict[process][p].values():
                    for n in dict[p].keys():
                        if n == 'voicenumber':
                            value = dict[p][n]
                            if type(value) != ListType: value = [value]
                            list[0] = val + "." + str(value[counter.count(val) % len(value)])
                        elif n in paramDict[process][val]:
                            value = dict[p][n]
                            if type(value) == BooleanType:
                                if value: value = 1
                                else: value = 0
                            if type(value) != ListType: value = [value]
                            pos = paramDict[process][val].index(n) + 1
                            if n == 'sound':
                                list[pos] = '"' + str(value[counter.count(val) % len(value)]) + '"'
                            else:
                                list[pos] = str(value[counter.count(val) % len(value)])
            nline = "i" + " ".join([i for i in list]) + "\n" 
            if post:
                print '\n' + nline
            port = 16000 + process
            osc.sendMsg('/event', [nline], "127.0.0.1", port)

def sendOscControl(value, address, port=8000, host='127.0.0.1'):
    """Sends a value from python to an osc port.
    
value = your_value
address = string_address
port = 8000
host = '127.0.0.1'

--- PARAMETERS ---

value : Numerical value to send on an OSC port.
address : A string that is the destination address. This takes the form of a file name with directories. 
port : The port on which to listen.
host : A string that is the intended host computer domain name. The default value ('127.0.0.1') is the current computer.
"""
    if type(value) != ListType:
        value = [value]
    osc.sendMsg(address, value, host, port)
    
def sendCsoundMsg(string, process=1):
    """Sends a message to csound stdin. Can be used to modify a ftable.
    
string = "csound message"
process = 1 (process number)

--- PARAMETERS ---

string : Csound message as a string (Usually a score line).
process : Ounk process number returned by startCsound(). This value is used to send the message to the intended Csound instance.
"""
    string = string + "\n"
    port = 16000 + process
    osc.sendMsg('/event', [string], "127.0.0.1", port)

def sendOscTrigger(value, address, port=8000, host='127.0.0.1'):
    """Sends a value from python to an OSC port and immediatly after sends -1 to the same port.
    
value = your_value
address = string_address
port = 8000
host = '127.0.0.1'

--- PARAMETERS ---

value : Numerical value to be triggered.
address : A string that is the destination address. This takes the form of a file name with directories. 
port : The port on which to listen.
host : A string that is the intended host computer domain name. The default value ('127.0.0.1') is the current computer.
"""

    osc.sendMsg(address, [value], host, port)
    osc.sendMsg(address, [-1], host, port)

        
######################### Controllers instruments ############################
######################################################
############### Midi release controllers #############
def linsegr(bus, i1, dur1, i2, dur2=None, i3=None, dur3=None, i4=None, dur4=None, i5=None, final=0, starttime=0, duration=None):
    """Generates a breakpoint line with a final release segment

bus = bus_output
i1 = first_point
dur1 = first_duration # dur* are in seconds
i2 = second_point
dur2 = None
i3 = None
dur3 = None
i4 = None
dur4 = None
i5 = None
final = 0 (final value)
starttime = 0
duration = None

--- PARAMETERS ---

bus : Name of the output control bus.
i1 : Starting value of the line.
dur1 : Duration, in seconds, of the first segment.
i2 : Second value of the line.
dur2 : Duration, in seconds, of the second segment (optional).
i3 : Third value of the line (optional).
dur3 : Duration, in seconds, of the third segment (optional).
i4 : Fourth value of the line (optional).
dur4 : Duration, in seconds, of the fourth segment (optional).
i5 : Fifth value of the line (optional).
final : Inside a MIDI instrument, line will reach final value after the release of the note.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'. Sum of segment's dur must equal duration.
"""
    if not duration: duration = GDUR
    if dur2 == None: dur2 = 0
    if i3 == None: i3 = i2
    if dur3 == None: dur3 = 0
    if i4 == None: i4 = i3
    if dur4 == None: dur4 = 0
    if i5 == None: i5 = i4
    duration, starttime, bus, i1, dur1, i2, dur2, i3, dur3, i4, dur4, i5, final = _convertToList(duration, starttime, bus, i1, dur1,
                                                                                                 i2, dur2, i3, dur3, i4, dur4, i5, final)
    seq = max(len(bus), len(i1), len(dur1), len(i2), len(dur2), len(i3), len(dur3), len(i4), len(dur4), len(i5), len(final), len(starttime), len(duration))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kbus%s linsegr %s, %s, %s, %s, " % (_wrap(bus,i), str(i1[i%len(i1)]), str(dur1[i%len(dur1)]), str(i2[i%len(i2)]), str(dur2[i%len(dur2)])))
            orchlines.append("%s, %s, %s, %s, %s, " % (str(i3[i%len(i3)]), str(dur3[i%len(dur3)]), str(i4[i%len(i4)]), str(dur4[i%len(dur4)]), str(i5[i%len(i5)])))
            orchlines.append("%s, %s\n" % (str(midiRelease), str(final[i%len(final)])))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('linsegr', 0, True)
        orchlines.append("instr %d\n" % instrument)
        orchlines.append("ksig linsegr p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)
        line = "i%s %s %s %s %s %s %s %s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(i1[i%len(i1)]), str(dur1[i%len(dur1)]), str(i2[i%len(i2)]), str(dur2[i%len(dur2)]), str(i3[i%len(i3)]), str(dur3[i%len(dur3)]), str(i4[i%len(i4)]), str(dur4[i%len(dur4)]), str(i5[i%len(i5)]), str(midiRelease), str(final[i%len(final)]))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'i1', 'dur1', 'i2', 'dur2', 'i3', 'dur3', 'i4', 'dur4', 'i5', 'midiRelease', 'final']
        _routeScoreline(line)

def expsegr(bus, i1, dur1, i2, dur2=None, i3=None, dur3=None, i4=None, dur4=None, i5=None, final=0.0001, starttime=0, duration=None):
    """Generates an exponential breakpoint envelope with a final release segment. Values must be non-zero and must agree in sign.

bus = bus_output
i1 = first_point
dur1 = first_duration # dur* are in seconds
i2 = second_point
dur2 = None
i3 = None
dur3 = None
i4 = None
dur4 = None
i5 = None
final = 0.0001 (final value)
starttime = 0
duration = None

--- PARAMETERS ---

bus : Name of the output control bus.
i1 : Starting value of the curve.
dur1 : Duration, in seconds, of the first segment.
i2 : Second value of the curve.
dur2 : Duration, in seconds, of the second segment (optional).
i3 : Third value of the curve (optional).
dur3 : Duration, in seconds, of the third segment (optional).
i4 : Fourth value of the curve (optional).
dur4 : Duration, in seconds, of the fourth segment (optional).
i5 : Fifth value of the curve (optional).
final : Inside a MIDI instrument, curve will reach final value after the release of the note.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'. Sum of segment's dur must equal duration.
"""
    if not duration: duration = GDUR
    if dur2 == None: dur2 = 0
    if i3 == None: i3 = i2
    if dur3 == None: dur3 = 0
    if i4 == None: i4 = i3
    if dur4 == None: dur4 = 0
    if i5 == None: i5 = i4
    duration, starttime, bus, i1, dur1, i2, dur2, i3, dur3, i4, dur4, i5, final = _convertToList(duration, starttime, bus, i1, dur1,
                                                                                                 i2, dur2, i3, dur3, i4, dur4, i5, final)
    seq = max(len(bus), len(i1), len(dur1), len(i2), len(dur2), len(i3), len(dur3), len(i4), len(dur4), len(i5), len(final), len(starttime), len(duration))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kbus%s expsegr %s, %s, %s, %s, " % (_wrap(bus,i), str(i1[i%len(i1)]), str(dur1[i%len(dur1)]), str(i2[i%len(i2)]), str(dur2[i%len(dur2)])))
            orchlines.append("%s, %s, %s, %s, %s, " % (str(i3[i%len(i3)]), str(dur3[i%len(dur3)]), str(i4[i%len(i4)]), str(dur4[i%len(dur4)]), str(i5[i%len(i5)])))
            orchlines.append("%s, %s\n" % (str(midiRelease), str(final[i%len(final)])))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('expsegr', 0, True)
        orchlines.append("instr %d\n" % instrument)
        orchlines.append("ksig expsegr p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)
        line = "i%s %s %s %s %s %s %s %s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(i1[i%len(i1)]), str(dur1[i%len(dur1)]), str(i2[i%len(i2)]), str(dur2[i%len(dur2)]), str(i3[i%len(i3)]), str(dur3[i%len(dur3)]), str(i4[i%len(i4)]), str(dur4[i%len(dur4)]), str(i5[i%len(i5)]), str(midiRelease), str(final[i%len(final)]))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'i1', 'dur1', 'i2', 'dur2', 'i3', 'dur3', 'i4', 'dur4', 'i5', 'midiRelease', 'final']
        _routeScoreline(line)


######################################################
################# k-rate controllers #################
def busMix(bus, in1, in2, ftype='add', duration=None, starttime=0):
    """Mixes two bus controllers together by means of addition or multiplication.

bus = bus_output
in1 = first_bus_input
in2 = second_bus_input
ftype = 'add' # 'add' or 'times'
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, bus, in1, in2, ftype = _convertToList(duration, starttime, bus, in1, in2, ftype)
    seq = max(len(bus), len(in1), len(in2), len(ftype), len(duration), len(starttime))

    if midiSynthesizer:
        for i in range(seq):
            if _wrap(ftype,1) == 'times':
                orchlines.append("kbus%s = kbus%s * kbus%s\n" % (_wrap(bus,i), str(in1[i%len(in1)]), str(in2[i%len(in2)])))
            else:    
                orchlines.append("kbus%s = kbus%s + kbus%s\n" % (_wrap(bus,i), str(in1[i%len(in1)]), str(in2[i%len(in2)])))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('busMix', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append('kin1 chnget "kbus%s"\n' % str(_kbusget(in1[i%len(in1)])))
        orchlines.append('kin2 chnget "kbus%s"\n' % str(_kbusget(in2[i%len(in2)])))
        if _wrap(ftype,i) == 'times':
            orchlines.append('chnset kin1 * kin2, "kbus%s"\n' % busset)
        else:
            orchlines.append('chnset kin1 + kin2, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        _routeScoreline(line)

def busScale(bus, mult=1, add=0, duration=None, starttime=0):
    """Adds and/or multiplies values to a bus controller.

bus = bus_to_modify
mult = 1
add = 0
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, bus, add, mult = _convertToList(duration, starttime, bus, add, mult)
    seq = max(len(bus), len(add), len(mult), len(duration), len(starttime))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kbus%s = kbus%s * %s + %s\n" % (_wrap(bus,i), _wrap(bus,i), _wrap(mult,i), _wrap(add,i)))
        return

    for i in range(seq):
        instrument = _checkInst('busScale', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append('kin chnget "kbus%s"\n' % str(_kbusget(_wrap(bus,i))))
        orchlines.append('chnset kin * p4 + p5, "kbus%s"\n' % str(_kbusget(_wrap(bus,i))))
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mult,i), _wrap(add,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mult', 'add']
        _routeScoreline(line)

def busMapper(bus, input, inmin=0, inmax=127, outmin=0, outmax=1, duration=None, starttime=0):
    """Maps input bus values inside inmin - inmax range according to output range outmin - outmax.
   
bus = bus_output
input = bus_input
inmin = 0
inmax = 127
outmin = 0
outmax = 1
starttime = 0
duration = None

--- PARAMETERS ---

bus : Name of the output control bus.
input : Name of the input control bus.
inmin : Minimum input value.
inmax : Maximum input value.
outmin : Minimum value of the resultant scale operation.
outmax : Maximum value of the resultant scale operation.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
"""    

    if not duration: duration = GDUR
    duration, starttime, bus, input, inmin, inmax, outmin, outmax = _convertToList(duration, starttime, bus, input, inmin, inmax, outmin, outmax)
    seq = max(len(bus), len(input), len(inmin), len(inmax), len(outmin), len(outmax), len(duration), len(starttime))

    if midiSynthesizer:
        raise Error('Not yet implemented')
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('busMapper', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append('kin chnget "kbus%s"\n' % str(_kbusget(_wrap(input,i))))
        orchlines.append("ksig init 1\n")
        orchlines.append("if p4 > p5 then\n")
        orchlines.append("iinmin = p5\niinmax = p4\niinrev = 1\n")
        orchlines.append("else\n")
        orchlines.append("iinmin = p4\niinmax = p5\niinrev = 0\n") 
        orchlines.append("endif\n") 
        orchlines.append("iinrange = iinmax - iinmin\n")      
        orchlines.append("if p6 > p7 then\n")
        orchlines.append("ioutmin = p7\nioutmax = p6\nioutrev = 1\n")
        orchlines.append("else\n")
        orchlines.append("ioutmin = p6\nioutmax = p7\nioutrev = 0\n")  
        orchlines.append("endif\n")
        orchlines.append("ioutrange = ioutmax - ioutmin\n")      

        orchlines.append("if kin < iinmin then\n")
        orchlines.append("kin = iinmin\nendif\n")
        orchlines.append("if kin > iinmax then\n")
        orchlines.append("kin = iinmax\nendif\n")
        orchlines.append("if iinrev == 1 then\n")
        orchlines.append("kfirstscale = (iinmax - kin) / iinrange\n")
        orchlines.append("else\n")
        orchlines.append("kfirstscale = (kin - iinmin) / iinrange\n")
        orchlines.append("endif\n")
        orchlines.append("if ioutrev == 1 then\n")
        orchlines.append("ksig = ioutmax - (kfirstscale * ioutrange)\n")
        orchlines.append("else\n")
        orchlines.append("ksig = kfirstscale * ioutrange + ioutmin\n")
        orchlines.append("endif\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(inmin,i), _wrap(inmax,i), _wrap(outmin,i), _wrap(outmax,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'inmin', 'inmax', 'outmin', 'outmax']
        _routeScoreline(line)

def readTable(bus, table, starttime=0, duration=None):
    """Reads a controller table once over the whole duration of the function.

bus = bus_output
table = table_number
starttime = 0
duration = None

--- PARAMETERS ---

bus : Name of the output control bus.
table : Table used as the envelope of the reader. Usually the value returned by a 'genXXX' function.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
"""
    if not duration: duration = GDUR
    duration, starttime, bus, table = _convertToList(duration, starttime, bus, table)
    seq = max(len(table), len(bus), len(duration), len(starttime))

    if midiSynthesizer:
        raise Error("You can't read a table inside a midiInstrument!")

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('readTable', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig oscil1i 0, 1, p3, p4\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(table,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'table']
        _routeScoreline(line)

def discreetTableLoop(bus, table, speed=0.1, step=1, starttime=0, duration=None, reinittrigbus=None, speedVar=None, stepVar=None):
    """Loops over discreet values in a table with control on time between each picked values and step. 

bus = bus_output
table = table_to_read
speed = 0.1 # sec.
step = 1
starttime = 0
duration = None
reinittrigbus = None # reinit_counter_trigger_bus
speedVar = None
stepVar = None
"""
    if not duration: duration = GDUR
    spe = stp = ''
    duration, starttime, bus, speed, step, table = _convertToList(duration, starttime, bus, speed, step, table)
    speedVar, stepVar, reinittrigbus = _convertVarToList(speedVar, stepVar, reinittrigbus)
    seq = max(len(bus), _len(reinittrigbus), len(speed), len(step), len(duration), len(starttime), len(table), _len(speedVar), _len(stepVar))

    if not 'discreetTableRead' in UDO:
        UDO.append('discreetTableRead')

    if midiSynthesizer:
        for i in range(seq):
            if reinittrigbus:
                orchlines.append('ktrig%d = kbus%s\n' % (i, _wrap(reinittrigbus,i)))
            else:
                orchlines.append('ktrig%d = 0\n' % i)
            orchlines.append("kval%d discreetTableRead ktrig%d, %s" % (i, i, _wrap(speed,i)))
            if speedVar:
                orchlines.append("*kbus%s" % _wrap(speedVar,i))
            orchlines.append(", %s" % _wrap(step,i))
            if stepVar:
                orchlines.append("*kbus%s" % _wrap(stepVar,i))
            orchlines.append(", %s\n" % _wrap(table,i))
            orchlines.append("kbus%s = kval%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('discreetTableLoop', 0, True)
        pval = 7
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if reinittrigbus:
            orchlines.append('Strig%dkbus ' % instrument)
            orchlines.append('sprintf "kbus%d"')
            orchlines.append(", p7\n")
            orchlines.append("ktrig chnget Strig%dkbus\n" % instrument)
            pval += 1
        else:
            orchlines.append("ktrig = 0\n")
        if speedVar:
            pval, spe = _setxxxVar(pval, 'spe')
        if stepVar:
            pval, stp = _setxxxVar(pval, 'stp')
        orchlines.append("ksig discreetTableRead ktrig, p4%s, p5%s, p6\n" % (spe, stp))
        #orchlines.append("printk2 ksig\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        if reinittrigbus:
            line = "i%s %s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(speed,i), _wrap(step,i), _wrap(table,i), _kbusget(_wrap(reinittrigbus,i)))
        else:
            line = "i%s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(speed,i), _wrap(step,i), _wrap(table,i))
        if speedVar: line += '%s ' % _kbusget(_wrap(speedVar,i))
        if stepVar: line += '%s ' % _kbusget(_wrap(stepVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'speed', 'step', 'table']
        if reinittrigbus: paramDict[procNum][str(instrument)].append('reinittrigbus')
        if speedVar: paramDict[procNum][str(instrument)].append('speedVar')
        if stepVar: paramDict[procNum][str(instrument)].append('stepVar')
        _routeScoreline(line)

def rando(bus, mini=0, maxi=1, starttime=0, duration=None, miniVar=None, maxiVar=None):
    """Generates random values at k-rate.

bus = bus_output
mini = 0
maxi = 1
starttime = 0
duration = None
miniVar = None
maxiVar = None
"""
    if not duration: duration = GDUR
    mi = ma = ''
    duration, starttime, bus, mini, maxi = _convertToList(duration, starttime, bus, mini, maxi)
    miniVar, maxiVar = _convertVarToList(miniVar, maxiVar)
    seq = max(len(bus), len(mini), len(maxi), len(duration), len(starttime), _len(miniVar), _len(maxiVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d random %s" % (i, _wrap(mini,i)))
            if miniVar:
                orchlines.append("*kbus%s" % _wrap(miniVar,i))
            orchlines.append(", %s" % _wrap(maxi,i))
            if maxiVar:
                orchlines.append("*kbus%s\n" % _wrap(maxiVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kbus%s = kran%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('rando', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if miniVar:
            pval, mi = _setxxxVar(pval, 'mi')
        if maxiVar:
            pval, ma = _setxxxVar(pval, 'ma')
        orchlines.append("ksig random p4%s, p5%s\n" % (mi, ma))
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mini,i), _wrap(maxi,i))
        if miniVar: line += '%s ' % _kbusget(_wrap(miniVar,i))
        if maxiVar: line += '%s ' % _kbusget(_wrap(maxiVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mini', 'maxi']
        if miniVar: paramDict[procNum][str(instrument)].append('miniVar')
        if maxiVar: paramDict[procNum][str(instrument)].append('maxiVar')
        _routeScoreline(line)

def trigRandom(bus, trigbus, mini=0, maxi=1, starttime=0, duration=None, miniVar=None, maxiVar=None):
    """Generates a new random value whenever receiving a trigger signal.

bus = bus_output
trigbus = trigger_bus
mini = 0
maxi = 1
starttime = 0
duration = None
miniVar = None
maxiVar = None
"""
    if not duration: duration = GDUR
    mi = ma = ''
    duration, starttime, bus, trigbus, mini, maxi = _convertToList(duration, starttime, bus, trigbus, mini, maxi)
    miniVar, maxiVar = _convertVarToList(miniVar, maxiVar)
    seq = max(len(bus), len(trigbus), len(mini), len(maxi), len(duration), len(starttime), _len(miniVar), _len(maxiVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kswitch%d init -1\n" % i)
            orchlines.append('kswitch%d = kbus%s\n' % (i, _wrap(trigbus,i)))
            orchlines.append("kswichanged%d changed kswitch%d\n" % (i, i))
            orchlines.append("kswichanged%d limit kswichanged%d, 0, 127\n" % (i, i))
            orchlines.append("kran%d trandom kswichanged%d, %s" % (i, i, _wrap(mini,i)))
            if miniVar:
                orchlines.append("*kbus%s" % _wrap(miniVar,i))
            orchlines.append(", %s" % _wrap(maxi,i))
            if maxiVar:
                orchlines.append("*kbus%s\n" % _wrap(maxiVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kbus%s = kran%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('trigRandom', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ktrig init -1\n")  
        orchlines.append('Strig%dkbus ' % instrument)
        orchlines.append('sprintf "kbus%d"')
        orchlines.append(", p6\n")
        orchlines.append("ktrig chnget Strig%dkbus\n" % instrument)
        orchlines.append("ktrig limit ktrig, 0, 127\n")
        orchlines.append("ksig init 1\n")
        if miniVar:
            pval, mi = _setxxxVar(pval, 'mi')
        if maxiVar:
            pval, ma = _setxxxVar(pval, 'ma')
        orchlines.append("ksig trandom ktrig, p4%s, p5%s\n" % (mi, ma))
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mini,i), _wrap(maxi,i), _kbusget(_wrap(trigbus,i)))
        if miniVar: line += '%s ' % _kbusget(_wrap(miniVar,i))
        if maxiVar: line += '%s ' % _kbusget(_wrap(maxiVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mini', 'maxi', 'trigbus']
        if miniVar: paramDict[procNum][str(instrument)].append('miniVar')
        if maxiVar: paramDict[procNum][str(instrument)].append('maxiVar')
        _routeScoreline(line)

def trigEnvelope(bus, trigbus, table='default', envdur=1, starttime=0, duration=None):
    """Reads a controller table, once on trigger signal, over the envdur duration.

bus = bus_output
trigbus = trigger_bus
table = 'default' # default is hanning table
envdur = 1 # seconds
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, bus, trigbus, table, envdur = _convertToList(duration, starttime, bus, trigbus, table, envdur)
    seq = max(len(bus), len(trigbus), len(table), len(envdur), len(duration), len(starttime))

    if not 'trigEnv' in UDO:
        UDO.append('trigEnv')
        
    if midiSynthesizer:
        for i in range(seq):
            tab = _wrap(table,i)
            if tab == 'default': tab = 6
            orchlines.append("ksig%d init 0\n" % i)
            orchlines.append("kswitch%d init -1\n" % i)
            orchlines.append('kswitch%d = kbus%s\n' % (i, _wrap(trigbus,i)))
            orchlines.append("kswichanged%d changed kswitch%d\n" % (i, i))
            orchlines.append("ksig%d trigEnv kswichanged%d, %s, %s\n" % (i, i, _wrap(envdur,i), tab))
            orchlines.append("kbus%s = ksig%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('trigEnvelope', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ktrig init -1\n")  
        orchlines.append("ksig init 0\n")
        orchlines.append('Strig%dkbus ' % instrument)
        orchlines.append('sprintf "kbus%d"')
        orchlines.append(", p6\n")
        orchlines.append("ktrig chnget Strig%dkbus\n" % instrument)
        orchlines.append("ksig trigEnv ktrig, p4, p5\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        tab = _wrap(table,i)
        if tab == 'default': tab = 6
        line = "i%s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(envdur,i), tab, _kbusget(_wrap(trigbus,i)))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'envdur', 'table', 'trigbus']
        _routeScoreline(line)

def randomi(bus, mini=0, maxi=1, rate=5, starttime=0, duration=None, miniVar=None, maxiVar=None, rateVar=None):
    """Generates random values with interpolation.

bus = bus_output
mini = 0
maxi = 1
rate = 5
starttime = 0
duration = None
miniVar = None
maxiVar = None
rateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
mini : Minimum range limit.
maxi : Maximum range limit.
rate : Frequency, in Hertz, of random break-point generation.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
miniVar : Name of the control bus multiplying mini value.
maxiVar : Name of the control bus multiplying maxi value.
rateVar : Name of the control bus multiplying rate value.
"""
    if not duration: duration = GDUR
    mi = ma = rat = ''
    duration, starttime, bus, mini, maxi, rate = _convertToList(duration, starttime, bus, mini, maxi, rate)
    miniVar, maxiVar, rateVar = _convertVarToList(miniVar, maxiVar, rateVar)
    seq = max(len(bus), len(mini), len(maxi), len(rate), len(duration), len(starttime), _len(miniVar), _len(maxiVar), _len(rateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d randomi %s" % (i, _wrap(mini,i)))
            if miniVar:
                orchlines.append("*kbus%s" % _wrap(miniVar,i))
            orchlines.append(", %s" % _wrap(maxi,i))
            if maxiVar:
                orchlines.append("*kbus%s" % _wrap(maxiVar,i))
            orchlines.append(", %s" % _wrap(rate,i))
            if rateVar:
                orchlines.append("*kbus%s\n" % _wrap(rateVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kbus%s = kran%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('randomi', 0, True)
        pval = 7
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if miniVar:
            pval, mi = _setxxxVar(pval, 'mi')
        if maxiVar:
            pval, ma = _setxxxVar(pval, 'ma')
        if rateVar:
            pval, rat = _setxxxVar(pval, 'rat')
        orchlines.append("ksig randomi p4%s, p5%s, p6%s\n" % (mi, ma, rat))
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mini,i), _wrap(maxi,i), _wrap(rate,i))
        if miniVar: line += '%s ' % _kbusget(_wrap(miniVar,i))
        if maxiVar: line += '%s ' % _kbusget(_wrap(maxiVar,i))
        if rateVar: line += '%s ' % _kbusget(_wrap(rateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mini', 'maxi', 'rate']
        if miniVar: paramDict[procNum][str(instrument)].append('miniVar')
        if maxiVar: paramDict[procNum][str(instrument)].append('maxiVar')
        if rateVar: paramDict[procNum][str(instrument)].append('rateVar')
        _routeScoreline(line)

def spline(bus, mini=0, maxi=1, minrate=5, maxrate=6, starttime=0, duration=None, miniVar=None, maxiVar=None, minrateVar=None, maxrateVar=None):
    """Generates random spline curves.

bus = bus_output
mini = 0
maxi = 1
minrate = 5
maxrate = 6
starttime = 0
duration = None
miniVar = None
maxiVar = None
minrateVar = None
maxrateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
mini : Minimum range limit.
maxi : Maximum range limit.
minrate : Minimum frequency, in Hertz, of point generation rate.
maxrate : Maximum frequency, in Hertz, of point generation rate.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
miniVar : Name of the control bus multiplying mini value.
maxiVar : Name of the control bus multiplying maxi value.
minrateVar : Name of the control bus multiplying minrate value.
maxrateVar : Name of the control bus multiplying maxrate value.

Real output range could be a bit greater of range values, because of interpolating curves beetween each pair of random-points. 
"""
    if not duration: duration = GDUR
    mi = ma = mira = mara = ''
    duration, starttime, bus, mini, maxi, minrate, maxrate = _convertToList(duration, starttime, bus, mini, maxi, minrate, maxrate)
    miniVar, maxiVar, minrateVar, maxrateVar = _convertVarToList(miniVar, maxiVar, minrateVar, maxrateVar)
    seq = max(len(bus), len(mini), len(maxi), len(minrate), len(maxrate), len(duration), len(starttime), 
              _len(miniVar), _len(maxiVar), _len(minrateVar), _len(maxrateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d rspline %s" % (i, _wrap(mini,i)))
            if miniVar:
                orchlines.append("*kbus%s" % _wrap(miniVar,i))
            orchlines.append(", %s" % _wrap(maxi,i))
            if maxiVar:
                orchlines.append("*kbus%s" % _wrap(maxiVar,i))
            orchlines.append(", %s" % _wrap(minrate,i))
            if minrateVar:
                orchlines.append("*kbus%s\n" % _wrap(minrateVar,i))
            orchlines.append(", %s" % _wrap(maxrate,i))
            if maxrateVar:
                orchlines.append("*kbus%s\n" % _wrap(maxrateVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kbus%s = kran%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('spline', 0, True)
        pval = 8
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if miniVar:
            pval, mi = _setxxxVar(pval, 'mi')
        if maxiVar:
            pval, ma = _setxxxVar(pval, 'ma')
        if minrateVar:
            pval, mira = _setxxxVar(pval, 'mira')
        if maxrateVar:
            pval, mara = _setxxxVar(pval, 'mara')
        orchlines.append("ksig rspline p4%s, p5%s, p6%s, p7%s\n" % (mi, ma, mira, mara))
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mini,i), _wrap(maxi,i), _wrap(minrate,i), _wrap(maxrate,i))
        if miniVar: line += '%s ' % _kbusget(_wrap(miniVar,i))
        if maxiVar: line += '%s ' % _kbusget(_wrap(maxiVar,i))
        if minrateVar: line += '%s ' % _kbusget(_wrap(minrateVar,i))
        if maxrateVar: line += '%s ' % _kbusget(_wrap(maxrateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mini', 'maxi', 'minrate', 'maxrate']
        if miniVar: paramDict[procNum][str(instrument)].append('miniVar')
        if maxiVar: paramDict[procNum][str(instrument)].append('maxiVar')
        if minrateVar: paramDict[procNum][str(instrument)].append('minrateVar')
        if maxrateVar: paramDict[procNum][str(instrument)].append('maxrateVar')
        _routeScoreline(line)
        
def randomh(bus, mini=0, maxi=1, rate=5, portamento=0, starttime=0, duration=None, miniVar=None, maxiVar=None, rateVar=None):
    """Generates random values and hold them.

bus = bus_output
mini = 0
maxi = 1
rate = 5
portamento = 0
starttime = 0
duration = None
miniVar = None
maxiVar = None
rateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
mini : Minimum range limit.
maxi : Maximum range limit.
rate : Frequency, in Hertz, of random break-point generation.
portamento : Ramp time before control signal reaches a new value.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
miniVar : Name of the control bus multiplying mini value.
maxiVar : Name of the control bus multiplying maxi value.
rateVar : Name of the control bus multiplying rate value.
"""
    if not duration: duration = GDUR
    mi = ma = rat = ''
    duration, starttime, bus, mini, maxi, rate, portamento = _convertToList(duration, starttime, bus, mini, maxi, rate, portamento)
    miniVar, maxiVar, rateVar = _convertVarToList(miniVar, maxiVar, rateVar)
    seq = max(len(bus), len(mini), len(maxi), len(rate), len(portamento), len(duration), len(starttime), _len(miniVar), _len(maxiVar), _len(rateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d randomh %s" % (i, _wrap(mini,i)))
            if miniVar:
                orchlines.append("*kbus%s" % _wrap(miniVar,i))
            orchlines.append(", %s" % _wrap(maxi,i))
            if maxiVar:
                orchlines.append("*kbus%s" % _wrap(maxiVar,i))
            orchlines.append(", %s" % _wrap(rate,i))
            if rateVar:
                orchlines.append("*kbus%s\n" % _wrap(rateVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("krand%d port kran%d, %s, 1\n" % (i, i, _wrap(portamento, i)))
            orchlines.append("kbus%s = krand%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('randomh', 0, True)
        pval = 8
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if miniVar:
            pval, mi = _setxxxVar(pval, 'mi')
        if maxiVar:
            pval, ma = _setxxxVar(pval, 'ma')
        if rateVar:
            pval, rat = _setxxxVar(pval, 'rat')
        orchlines.append("ksig randomh p4%s, p5%s, p6%s\n" % (mi, ma, rat))
        orchlines.append("ksig2 port ksig, p7, 1\n")
        orchlines.append('chnset ksig2, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(mini,i), _wrap(maxi,i), _wrap(rate,i), _wrap(portamento, i))
        if miniVar: line += '%s ' % _kbusget(_wrap(miniVar,i))
        if maxiVar: line += '%s ' % _kbusget(_wrap(maxiVar,i))
        if rateVar: line += '%s ' % _kbusget(_wrap(rateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'mini', 'maxi', 'rate', 'portamento']
        if miniVar: paramDict[procNum][str(instrument)].append('miniVar')
        if maxiVar: paramDict[procNum][str(instrument)].append('maxiVar')
        if rateVar: paramDict[procNum][str(instrument)].append('rateVar')
        _routeScoreline(line)

def randomChoice(bus, choice, rate=5, portamento=0, duration=None, starttime=0, rateVar=None):
    """Chooses values randomly in a list and hold them.

bus = bus_output
choice = list_of_value
rate = 5
portamento = 0
starttime = 0
duration = None
rateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
choice : List of values to choose from.
rate : Frequency, in Hertz, of random break-point generation.
portamento : Ramp time before control signal reaches a new value.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
rateVar : Name of the control bus multiplying rate value.
"""
    global fnum
    if not duration: duration = GDUR

    for i in range(24):
        size = math.pow(2,(i+1))
        if size >= len(choice):
            break

    mi = ma = rat = ''
    duration, starttime, bus, rate, portamento = _convertToList(duration, starttime, bus, rate, portamento)
    rateVar = _convertVarToList(rateVar)
    if ListType in [type(ele) for ele in choice]:
        fnchlist = True
        seq = max(len(bus), len(rate), len(duration), len(starttime), len(choice), len(portamento), _len(rateVar))
    else:
        fnchlist = False
        seq = max(len(bus), len(rate), len(duration), len(starttime), len(portamento), _len(rateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d randomh 0, %s, %s" % ((len(choice)-.01), _wrap(rate,i)))
            if rateVar:
                orchlines.append("*kbus%s\n" % _wrap(rateVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kround%d = round(kran%d)\n" % (i, i))
            orchlines.append("kchoice%d table kround%d, %d\n" % (i, i, fnum))
            orchlines.append("kport%d port kchoice%d, %s, 1\n" % (i, i, _wrap(portamento,i)))
            orchlines.append("kbus%s = kport%d\n" % (_wrap(bus, i), i))
        return

    if not fnchlist:
        fnum += 1
        listnum = fnum
        padding = [choice[0] for i in range(int(size) - len(choice))]
        scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in choice]) + " " + " ".join([str(n) for n in padding]) + '\n')
    
    for i in range(seq):
        if fnchlist:
            fnum += 1
            listnum = fnum
            padding = [choice[i][0] for i in range(int(size) - len(choice[i]))]
            scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in choice[i]]) + " " + " ".join([str(n) for n in padding]) + '\n')
        
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('randomChoice', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if rateVar:
            pval, rat = _setxxxVar(pval, 'rat')
        if not fnchlist:
            orchlines.append("ksig randomh 0, %s, p4%s\n" % (len(choice), rat))
        else:    
            orchlines.append("ksig randomh 0, %s, p4%s\n" % (len(choice[i]), rat))
        orchlines.append("kround = round(ksig)\n")
        orchlines.append("kchoice table kround, %d\n" % fnum)
        orchlines.append("kport port kchoice, p5, 1\n")
        orchlines.append('chnset kport, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(rate,i), _wrap(portamento,i))
        if rateVar: line += '%s ' % _kbusget(_wrap(rateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'rate', 'portamento']
        if rateVar: paramDict[procNum][str(instrument)].append('rateVar')
        _routeScoreline(line)

def weightedRandomChoice(bus, choice, rate=5, portamento=0, duration=None, starttime=0, rateVar=None):
    """Chooses randomly an element from a list, not uniformly, but using a given weight for each element, and hold them.

bus = bus_output
choice = list_of_tuple # (value, weight)
rate = 5
portamento = 0
starttime = 0
duration = None
rateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
choice : List of tuples containing value to choose and their weight. This parameter can't be a list of list!
rate : Frequency, in Hertz, of random break-point generation.
portamento : Ramp time before control signal reaches a new value.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
rateVar : Name of the control bus multiplying rate value.
"""
    global fnum
    if not duration: duration = GDUR

    valLen = sum([i[1] for i in choice])
    
    for i in range(24):
        size = math.pow(2,(i+1))
        if size >= valLen:
            break

    mi = ma = rat = ''
    duration, starttime, bus, rate, portamento = _convertToList(duration, starttime, bus, rate, portamento)
    rateVar = _convertVarToList(rateVar)
    seq = max(len(bus), len(rate), len(duration), len(starttime), len(choice), len(portamento), _len(rateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kran%d init 1\n" % i)
            orchlines.append("kran%d randomh 0, %s, %s" % ((valLen-.01), _wrap(rate,i)))
            if rateVar:
                orchlines.append("*kbus%s\n" % _wrap(rateVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kround%d = round(kran%d)\n" % (i, i))
            orchlines.append("kchoice%d table kround%d, %d\n" % (i, i, fnum))
            orchlines.append("kport%d port kchoice%d, %s, 1\n" % (i, i, _wrap(portamento,i)))
            orchlines.append("kbus%s = kport%d\n" % (_wrap(bus, i), i))
        return

    completeList = []
    for ch in choice:
        completeList.extend([ch[0] for i in range(ch[1])])
    fnum += 1
    listnum = fnum
    padding = [choice[0][0] for i in range(int(size) - valLen)]
    scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n) for n in completeList]) + " " + " ".join([str(n) for n in padding]) + '\n')
    
    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('weigthRandomChoice', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ksig init 1\n")
        if rateVar:
            pval, rat = _setxxxVar(pval, 'rat')
        orchlines.append("ksig randomh 0, %s, p4%s\n" % (valLen-.01, rat))
        orchlines.append("kround = round(ksig)\n")
        orchlines.append("kchoice table kround, %d\n" % fnum)
        orchlines.append("kport port kchoice, p5, 1\n")
        orchlines.append('chnset kport, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(rate,i), _wrap(portamento,i))
        if rateVar: line += '%s ' % _kbusget(_wrap(rateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'rate', 'portamento']
        if rateVar: paramDict[procNum][str(instrument)].append('rateVar')
        _routeScoreline(line)

def lfo(bus, frequency=1, amplitude=1, wavetype='sine',  offset=1, starttime=0, duration=None, frequencyVar=None, amplitudeVar=None):
    """Generates a low frequency oscillator with different waveshapes.

bus = bus_output
frequency = 1
amplitude = 1
wavetype = 'sine'
offset = 1
starttime = 0
duration = None
frequencyVar = None
amplitudeVar = None

wavetype can be 'sine', 'triangle', 'bisquare', 'unisquare', 'sawtooth', 'sawtoothdown'

--- PARAMETERS ---

bus : Name of the output control bus.
frequency : Frequency, in Hertz, of oscillator.
amplitude : Amplitude of oscillator.
wavetype : Determine the waveform of the oscillator, default to 'sine'. Possible wavetypes are 'sine', 'triangle', 'bisquare', 'unisquare', 'sawtooth', 'sawtoothdown'. 
offset : Value added to the output of the oscillator.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
frequencyVar : Name of the control bus multiplying frequency value.
amplitudeVar : Name of the control bus multiplying amplitude value.
"""
    if not duration: duration = GDUR
    freq = amp = ''
    duration, starttime, bus, frequency, amplitude, wavetype, offset = _convertToList(duration, starttime, bus, frequency,
                                                                                      amplitude, wavetype, offset)
    frequencyVar, amplitudeVar = _convertVarToList(frequencyVar, amplitudeVar)
    seq = max(len(bus), len(frequency), len(amplitude), len(wavetype), len(duration), len(starttime), _len(frequencyVar), _len(amplitudeVar))

    typeDict = {'sine': 0, 'triangle': 1, 'bisquare': 2, 'unisquare': 3, 'sawtooth': 4, 'sawtoothdown': 5}

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("klfo%d lfo %s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s" % _wrap(frequency,i))
            if frequencyVar:
                orchlines.append("*kbus%s" % _wrap(frequencyVar,i))
            orchlines.append(", %s\n" % typeDict[_wrap(wavetype,i)])
            orchlines.append("kbus%s = klfo%d+%s\n" % (_wrap(bus,i), i, _wrap(offset,i)))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('lfo', 0, True)
        pval = 8
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if frequencyVar:
            pval, freq = _setxxxVar(pval, 'freq')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        orchlines.append("ksig lfo p5%s, p4%s, p6\n" % (amp, freq))
        orchlines.append('chnset ksig + p7, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(frequency,i), _wrap(amplitude,i), str(typeDict[_wrap(wavetype,i)]), _wrap(offset,i))
        if frequencyVar: line += '%s ' % _kbusget(_wrap(frequencyVar,i))
        if amplitudeVar: line += '%s ' % _kbusget(_wrap(amplitudeVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'frequency', 'amplitude', 'wavetype', 'offset']
        if frequencyVar: paramDict[procNum][str(instrument)].append('frequencyVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        _routeScoreline(line)

def lfo2(bus, frequency=1, amplitude=1, table='default', offset=1, starttime=0, duration=None, frequencyVar=None, amplitudeVar=None):
    """Generates a low frequency oscillator whose waveform is defined in a csound table, usually by using 'genWaveform' or 'genLineseg'.

bus = bus_output
frequency = 1
amplitude = 1
table = 'default' # or a table generated with gen* functions
offset = 1
starttime = 0
duration = None
frequencyVar = None
amplitudeVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
frequency : Frequency, in Hertz, of oscillator.
amplitude : Amplitude of oscillator.
table : Table used as the waveform of the oscillator. Usually the value returned by 'genWaveform', 'genExpseg' or 'genLineseg'.
offset : Value added to the output of the oscillator.
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
frequencyVar : Name of the control bus multiplying frequency value.
amplitudeVar : Name of the control bus multiplying amplitude value.
"""
    if not duration: duration = GDUR
    freq = amp = ''
    duration, starttime, bus, frequency, amplitude, table, offset = _convertToList(duration, starttime, bus, frequency,
                                                                                      amplitude, table, offset)
    frequencyVar, amplitudeVar = _convertVarToList(frequencyVar, amplitudeVar)
    seq = max(len(bus), len(frequency), len(amplitude), len(table), len(duration), len(starttime), _len(frequencyVar), _len(amplitudeVar))

    if midiSynthesizer:
        for i in range(seq):
            tab = _wrap(table,i)
            if tab == 'default': tab = 1
            orchlines.append("kosc%d oscili %s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s" % _wrap(frequency,i))
            if frequencyVar:
                orchlines.append("*kbus%s" % _wrap(frequencyVar,i))
            orchlines.append(", %s\n" % tab)
            orchlines.append("kbus%s = kosc%d+%s\n" % (_wrap(bus,i), i, _wrap(offset,i)))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('lfo2', 0, True)
        pval = 8
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if frequencyVar:
            pval, freq = _setxxxVar(pval, 'freq')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        orchlines.append("ksig oscili p5%s, p4%s, p6\n" % (amp, freq))
        orchlines.append('chnset ksig + p7, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)
        
        tab = _wrap(table,i)
        if tab == 'default': tab = 1
        line = "i%s %s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(frequency,i), _wrap(amplitude,i), tab, _wrap(offset,i))
        if frequencyVar: line += '%s ' % _kbusget(_wrap(frequencyVar,i))
        if amplitudeVar: line += '%s ' % _kbusget(_wrap(amplitudeVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'frequency', 'amplitude', 'table', 'offset']
        if frequencyVar: paramDict[procNum][str(instrument)].append('frequencyVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        _routeScoreline(line)

def mouse(xbus, ybus, period=0.05, xmin=0, xmax=1, ymin=0, ymax=1, duration=None, starttime=0):
    """Retreives the mouse position and sends it on a controller bus.

xbus = bus_output_x_pos
ybus = bus_output_y_pos
period = 0.05
xmin = 0
xmax = 1
ymin = 0
ymax = 1
starttime = 0
duration = None
"""
    global display
    display = '--displays'
    if not duration: duration = GDUR
    duration, starttime, xbus, ybus, period, xmin, xmax, ymin, ymax = _convertToList(duration, starttime, xbus, ybus,
                                                                                     period, xmin, xmax, ymin, ymax)
    seq = 1

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("istartx = (%s-%s)/2+%s\n" % (_wrap(xmax,i), _wrap(xmin,i), _wrap(xmin,i)))
            orchlines.append("istarty = (%s-%s)/2+%s\n" % (_wrap(ymax,i), _wrap(ymin,i), _wrap(ymin,i)))
            orchlines.append("kx, ky xyin %s, %s, %s, %s, %s, istartx, istarty\n" % (_wrap(period,i), _wrap(xmin,i), _wrap(xmax,i), _wrap(ymin,i), _wrap(ymax,i)))
            orchlines.append("kx2 port kx, %s\n" % _wrap(period,i))
            orchlines.append("ky2 port ky, %s\n" % _wrap(period,i))
            orchlines.append("kbus%s = kx2\n" % _wrap(xbus,i))
            orchlines.append("kbus%s = ky2\n" % _wrap(ybus,i))
        return

    for i in range(seq):
        xbusset = _kbusset(_wrap(xbus,i))
        ybusset = _kbusset(_wrap(ybus,i))
        instrument = _checkInst('mouse', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("istartx = (p6-p5)/2+p5\n")
        orchlines.append("istarty = (p8-p7)/2+p7\n")
        orchlines.append("kx, ky xyin p4, p5, p6, p7, p8, istartx, istarty\n")
        orchlines.append("kx2 lineto kx, p4\n")
        orchlines.append("ky2 lineto ky, p4\n")
        orchlines.append('chnset kx2, "kbus%s"\n' % xbusset)
        orchlines.append('chnset ky2, "kbus%s"\n' % ybusset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(period,i), _wrap(xmin,i), _wrap(xmax,i), _wrap(ymin,i), _wrap(ymax,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'period', 'xmin', 'xmax', 'ymin', 'ymax']
        _routeScoreline(line)

def keyPressed(bus, duration=None, starttime=0):
    """Retreives the ASCII code of the key pressed on the keyboard and sends it on a controller bus.

bus = bus_output
starttime = 0
duration = None

* does not work inside Ounk environment
"""
    if not duration: duration = GDUR
    duration, starttime, bus = _convertToList(duration, starttime, bus)

    seq = 1

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kkey sensekey\n")
            orchlines.append("kchanged changed kkey\n")
            orchlines.append("if kchanged == 1 && kkey != -1 then\n")
            orchlines.append("kbus%s = kkey\n" % _wrap(bus,i))
            orchlines.append("kkey = -1\n")
            orchlines.append("endif\n")
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('keyPressed', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("kkey sensekey\n")
        orchlines.append("kchanged changed kkey\n")
        orchlines.append("if kchanged == 1 then\n")
        orchlines.append('chnset kkey, "kbus%s"\n' % busset)
        orchlines.append("endif\nendin\n\n")

        line = "i%s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        _routeScoreline(line)

def midiCtl(bus, midichannel=1, ctlnumber=1, minscale=0, maxscale=127, duration=None, starttime=0):
    """Takes a midi controller input and sends it on a controller bus.

bus = bus_output
midichannel = 1
ctlnumber = 1
minscale = 0
maxscale = 127
starttime = 0
duration = None
"""
    global midi
    midi = '-M%d ' % mididev
    if not duration: duration = GDUR
    duration, starttime, bus, midichannel, ctlnumber, minscale, maxscale = _convertToList(duration, starttime, bus, midichannel,
                                                                                          ctlnumber, minscale, maxscale)
    seq = max(len(bus), len(midichannel), len(ctlnumber), len(duration), len(starttime), len(minscale), len(maxscale))

    if midiSynthesizer:
        raise Error("You can't use midiCtl inside misiSynth, use midiSynthCtl instead.")
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('midiCtl', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append("ctrlinit p4, p5, 0\n")
        orchlines.append("ksig chanctrl p4, p5, p6, p7\n")
        orchlines.append("ksig2 lineto ksig, 0.025\n")
        orchlines.append('chnset ksig2, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(midichannel,i), _wrap(ctlnumber,i), _wrap(minscale,i), _wrap(maxscale,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'midichannel', 'ctlnumber', 'minscale', 'maxscale']
        _routeScoreline(line)

def midiTrigger(bus, value=1, midichannel=1, ctlnumber=1, duration=None, starttime=0):
    """Sends a value on a controller bus when a midi controller is positive and immediatly after sends -1.

bus = bus_output
value = 1
midichannel = 1
ctlnumber = 1
starttime = 0
duration = None
"""
    global midi
    midi = '-M%d ' % mididev
    if not duration: duration = GDUR
    duration, starttime, bus, midichannel, ctlnumber, value = _convertToList(duration, starttime, bus, midichannel, ctlnumber, value)
    seq = max(len(bus), len(midichannel), len(ctlnumber), len(duration), len(starttime), len(value))

    if midiSynthesizer:
        raise Error("You can't use midiTrigger inside misiSynth.")         
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('midiTrigger', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append("ctrlinit p4, p5, 0\n")
        orchlines.append("kopen init 0\n")
        orchlines.append("if kopen == 1 then\n")
        orchlines.append("kvalue = -1\n")
        orchlines.append('chnset kvalue, "kbus%s"\n' % busset)
        orchlines.append("kopen = 0\n")
        orchlines.append("endif\n")
        orchlines.append("ksig chanctrl p4, p5\n")
        orchlines.append("kchanged changed ksig\n")
        orchlines.append("if kchanged == 1 then\n")
        orchlines.append("if ksig != 0 then\n")
        orchlines.append("kvalue = %s\n" % _wrap(value,i))
        orchlines.append('chnset kvalue, "kbus%s"\n' % busset)
        orchlines.append("kopen = 1\n")
        orchlines.append("endif\n")
        orchlines.append("endif\n")
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(midichannel,i), _wrap(ctlnumber,i), _wrap(value,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'midichannel', 'ctlnumber', 'value']
        _routeScoreline(line)

def midiTriggerInc(bus, maxvalue=1, midichannel=1, ctlnumber=1, onevoice=True, duration=None, starttime=0):
    """Sends a value, starting at 1, on a controller bus when a midi controller is positive and immediatly after sends -1. The value is incremented by 1 until maxvalue is reached.

bus = bus_output
maxvalue = 1
midichannel = 1
ctlnumber = 1
onevoice = True
starttime = 0
duration = None
"""
    global midi, fnum
    midi = '-M%d ' % mididev
    if not duration: duration = GDUR
    duration, starttime, bus, midichannel, ctlnumber, maxvalue, onevoice = _convertToList(duration, starttime, bus, midichannel, ctlnumber, maxvalue, onevoice)
    seq = max(len(bus), len(midichannel), len(ctlnumber), len(duration), len(starttime), len(maxvalue), len(onevoice))

    if midiSynthesizer:
        raise Error("You can't use midiTriggerInc inside misiSynth.")         
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('midiTriggerInc', 0, True)

        for i in range(24):
            size = math.pow(2,(i+1))
            if size >= _wrap(maxvalue,i):
                break
        fnum += 1
        scorelines.append("f" + str(fnum) + " 0 " + str(int(size)) + " -2 " + " ".join([str(n+1) for n in range(_wrap(maxvalue,i))]) + '\n')

        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append("ctrlinit p4, p5, 0\n")
        orchlines.append("kpos init 0\n")
        orchlines.append("klast init 0\n")
        orchlines.append("kopen init 0\n")
        orchlines.append("ksig init 0\n")
        orchlines.append("kval init 0\n")
        orchlines.append("if kopen == 3 then\n")
        orchlines.append("kvalue = -1\n")
        orchlines.append('chnset kvalue, "kbus%s"\n' % busset)
        orchlines.append("kopen = 0\n")
        orchlines.append("elseif kopen == 2 then\n")
        orchlines.append('chnset klast, "kbus%s"\n' % busset)
        orchlines.append("kopen = 3\n")
        orchlines.append("elseif kopen == 1 then\n")
        orchlines.append("kvalue = -1\n")
        orchlines.append('chnset kvalue, "kbus%s"\n' % busset)
        if _wrap(onevoice,i):
            orchlines.append("kopen = 2\n")
        else:    
            orchlines.append("kopen = 0\n") 
        orchlines.append("elseif kopen == 0 then\n")
        orchlines.append("ksig chanctrl p4, p5\n")
        orchlines.append("kchanged changed ksig\n")
        orchlines.append("if kchanged == 1 then\n")
        orchlines.append("if ksig != 0 then\n")
        orchlines.append("kpo wrap kpos, 0, %s\n" % _wrap(maxvalue,i))
        orchlines.append("klast = kval\n")
        orchlines.append("kval table kpo, %d\n" % fnum)
        orchlines.append("kvalue = kval\n")
        orchlines.append('chnset kvalue, "kbus%s"\n' % busset)  
        orchlines.append("kopen = 1\n")
        orchlines.append("kpos = kpos+1\n")
        orchlines.append("endif\n")
        orchlines.append("endif\n")
        orchlines.append("endif\n")
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(midichannel,i), _wrap(ctlnumber,i), _wrap(maxvalue,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'midichannel', 'ctlnumber', 'maxvalue']
        _routeScoreline(line)

def printMidiCtl(duration=30):
    """Prints Midi controller info to the console without the need to startCsound().
    
duration = 30

* Do not use this function in a script"""    
    global midi
    midi = '-M%d ' % mididev
    if not duration: duration = 30
    instrument = _checkInst('printMidiCtl', 0, True)
    orchlines.append("massign 0, %d\n\n" % instrument)
    orchlines.append("instr %d\n" % instrument)
    orchlines.append("kstatus, kchan, kdata1, kdata2    midiin\n")
    orchlines.append("if (kstatus == 176) then\n")
    orchlines.append('printks "Midi controller: channel = %d, ctl number = %d, value = %d\\n", 0.1, kchan, kdata1, kdata2\n')
    orchlines.append("endif\n")
    orchlines.append("endin\n\n")
    
    line = "i%s 0 %s\n" % (str(instrument), str(duration))
    scorelines.append(line)
    
    startCsound(duration)
    
def oscReceive(bus, address, port, datatype='f', portamento=0, duration=None, starttime=0):
    """Receives data from an OSC port and sends it on  a controller bus.

bus = bus_output
address = string_address
port = port_input
datatype = 'f'
portamento = 0
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, bus, address, port, datatype, portamento = _convertToList(duration, starttime, bus, address, port, datatype, portamento)
    seq = max(len(bus), len(port), len(datatype), len(address), len(portamento), len(duration), len(starttime))

    for p in port:
        oscPort.append(str(p))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kin%d init 0\n" % i)
            orchlines.append('kk OSClisten gi%s, "%s", "%s", kin%d\n' % (_wrap(port,i), _wrap(address,i), _wrap(datatype,i), i))
            if portamento:
                orchlines.append("ksig%d port kin%d, %s\n" % (i, i, _wrap(portamento,i)))
            else:
                orchlines.append("ksig%d = kin%d\n" % (i, i))
            orchlines.append("kbus%s = ksig%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('oscReceive', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append("kin init 0\n")
        orchlines.append('kk OSClisten gi%s, "%s", "%s", kin\n' % (_wrap(port,i), _wrap(address,i), _wrap(datatype,i)))
        if portamento:
            orchlines.append("ksig port kin, %s\n" % _wrap(portamento,i))
        else:
            orchlines.append("ksig = kin\n")        
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        _routeScoreline(line)

def oscSend(input, address, port, host='127.0.0.1', datatype='f', duration=None, starttime=0):
    """Sends data on an OSC port.

input = bus_input
address = string_address
port = port_input
host = '127.0.0.1'
datatype = 'f'
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, input, address, port, host, datatype = _convertToList(duration, starttime, input, address, port, host, datatype)
    seq = max(len(input), len(port), len(datatype), len(address), len(duration), len(starttime))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append('OSCsend kbus%d, "%s", %s, "%s", "%s", kbus%d\n' % (_wrap(input,i), _wrap(host,i), _wrap(port,i), _wrap(address,i), _wrap(datatype,i), _wrap(input,i)))
        return

    for i in range(seq):
        instrument = _checkInst('oscSend', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append('kin chnget "kbus%s"\n' % str(_kbusget(_wrap(input,i))))
        orchlines.append('OSCsend kin, "%s", %s, "%s", "%s", kin\n' % (_wrap(host,i), _wrap(port,i), _wrap(address,i), _wrap(datatype,i)))
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        _routeScoreline(line)

def oscTriggerSend(address, port, host='127.0.0.1', datatype='f', duration=None, starttime=0):
    """Sends 1 at init on an OSC port and after sends 0's.

address = string_address
port = port_input
host = '127.0.0.1'
datatype = 'f'
starttime = 0
duration = None
"""
    if not duration: duration = GDUR
    duration, starttime, address, port, host, datatype = _convertToList(duration, starttime, address, port, host, datatype)
    seq = max(len(port), len(datatype), len(address), len(duration), len(starttime))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kra rand 1\n")
            orchlines.append("koscTrig init 1\n")
            orchlines.append('OSCsend kra, "%s", %s, "%s", "%s", koscTrig\n' % (_wrap(host,i), _wrap(port,i), _wrap(address,i), _wrap(datatype,i)))
            orchlines.append("koscTrig = 0\n")
        return

    for i in range(seq):
        instrument = _checkInst('oscTriggerSend', 0, True)
        orchlines.append("instr %s\n" % instrument)
        _checkTrigged()
        orchlines.append("kra rand 1\n")
        orchlines.append("koscTrig init 1\n")
        orchlines.append('OSCsend kra, "%s", %s, "%s", "%s", koscTrig\n' % (_wrap(host,i), _wrap(port,i), _wrap(address,i), _wrap(datatype,i)))
        orchlines.append("koscTrig = 0\n")
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s\n" % (str(instrument), _wrap(starttime,i), _wrap(duration,i))
        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        _routeScoreline(line)

def vibrato(bus, frequency=5, amplitude=0.1, delay=0.5, slopedur=1, amplituderand=0.1, frequencyrand=0.2, ampminrate=1, ampmaxrate=3, 
            freqminrate=1, freqmaxrate=3, starttime=0, duration=None, frequencyVar=None, amplitudeVar=None,
            amplituderandVar=None, frequencyrandVar=None, ampminrateVar=None, ampmaxrateVar=None, freqminrateVar=None, freqmaxrateVar=None):
    """Generates a vibrato controller.

bus = bus_output
frequency = 5
amplitude = 0.1
delay = 0.5
slopedur = 1
amplituderand = 0.1
frequencyrand = 0.2
ampminrate = 1
ampmaxrate = 3
freqminrate = 1
freqmaxrate = 3
starttime = 0
duration = None
amplitudeVar = None
frequencyVar = None
amplituderandVar = None
frequencyrandVar = None
ampminrateVar = None
ampmaxrateVar = None
freqminrateVar = None
freqmaxrateVar = None

--- PARAMETERS ---

bus : Name of the output control bus.
frequency : Average frequency value of vibrato (in hertz).
amplitude : Average amplitude value of vibrato.
delay : Delay, in seconds, before rising of the vibrato.
slopedur : Duration, in seconds, of the rising.
amplituderand : Amount of random amplitude deviation.
frequencyrand : Amount of random frequency deviation
ampminrate : Minimum frequency of random amplitude deviation segments (in hertz). 
ampmaxrate : Maximum frequency of random amplitude deviation segments (in hertz).
freqminrate : Minimum frequency of random frequency deviation segments (in hertz). 
freqmaxrate : Maximum frequency of random frequency deviation segments (in hertz).
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
frequencyVar : Name of the control bus multiplying frequency value.
amplitudeVar : Name of the control bus multiplying amplitude value.
amplituderandVar : Name of the control bus multiplying amplituderand value.
frequencyrandVar : Name of the control bus multiplying frequencyrand value.
ampminrateVar : Name of the control bus multiplying ampminrate value.
ampmaxrateVar : Name of the control bus multiplying ampmaxrate value.
freqminrateVar : Name of the control bus multiplying freqminrate value.
freqmaxrateVar : Name of the control bus multiplying freqmaxrate value.
"""
    if not duration: duration = GDUR
    amp = freq = amrd = frrd = amin = amax = fmin = fmax = ''
    bus, duration, starttime, frequency, amplitude, delay, slopedur = _convertToList(bus, duration, starttime, frequency,
                                                                                     amplitude, delay, slopedur)
    amplituderand, frequencyrand, ampminrate, ampmaxrate, freqminrate, freqmaxrate = _convertToList(amplituderand, frequencyrand,
                                                                                    ampminrate, ampmaxrate, freqminrate, freqmaxrate)
    frequencyVar, amplitudeVar, amplituderandVar, frequencyrandVar = _convertVarToList(frequencyVar, amplitudeVar, amplituderandVar, frequencyrandVar)
    ampminrateVar, ampmaxrateVar, freqminrateVar, freqmaxrateVar = _convertVarToList(ampminrateVar, ampmaxrateVar, freqminrateVar, freqmaxrateVar)
    seq = max(len(bus), len(duration), len(starttime), len(frequency), len(amplitude), len(delay), len(slopedur),
              len(amplituderand), len(frequencyrand), len(ampminrate), len(ampmaxrate), len(freqminrate), len(freqmaxrate),
              _len(amplitudeVar), _len(frequencyVar), _len(amplituderandVar), _len(frequencyrandVar), 
              _len(ampminrateVar), _len(ampmaxrateVar), _len(freqminrateVar), _len(freqmaxrateVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kslope%d linseg 0, %s, 0, %s, 1, 1, 1\n" % (i, _wrap(delay,i), _wrap(slopedur,i)))
            orchlines.append("kvib%d vibrato kslope%d*%s" % (i, i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s" % _wrap(frequency,i))
            if frequencyVar:
                orchlines.append("*kbus%s" % _wrap(frequencyVar,i))
            orchlines.append(", %s" % _wrap(amplituderand,i))
            if amplituderandVar:
                orchlines.append("*kbus%s" % _wrap(amplituderandVar,i))
            orchlines.append(", %s" % _wrap(frequencyrand,i))
            if frequencyrandVar:
                orchlines.append("*kbus%s" % _wrap(frequencyrandVar,i))
            orchlines.append(", %s" % _wrap(ampminrate,i))
            if ampminrateVar:
                orchlines.append("*kbus%s" % _wrap(ampminrateVar,i))
            orchlines.append(", %s" % _wrap(ampmaxrate,i))
            if ampmaxrateVar:
                orchlines.append("*kbus%s" % _wrap(ampmaxrateVar,i))
            orchlines.append(", %s" % _wrap(freqminrate,i))
            if freqminrateVar:
                orchlines.append("*kbus%s" % _wrap(freqminrateVar,i))
            orchlines.append(", %s" % _wrap(freqmaxrate,i))
            if freqmaxrateVar:
                orchlines.append("*kbus%s" % _wrap(freqmaxrateVar,i))
            orchlines.append(", 1\n")
            orchlines.append("kbus%s = 1 + kvib%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('vibrato', 0, True)
        pval = 14
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')        
        if frequencyVar:
            pval, freq = _setxxxVar(pval, 'freq')
        if amplituderandVar:
            pval, amrd = _setxxxVar(pval, 'amrd')        
        if frequencyrandVar:
            pval, frrd = _setxxxVar(pval, 'frrd')        
        if ampminrateVar:
            pval, amin = _setxxxVar(pval, 'amin')        
        if ampmaxrateVar:
            pval, amax = _setxxxVar(pval, 'amax')        
        if freqminrateVar:
            pval, fmin = _setxxxVar(pval, 'fmin')        
        if freqmaxrateVar:
            pval, fmax = _setxxxVar(pval, 'fmax')
            
        orchlines.append("kslope linseg 0, p12, 0, p13, 1, p3-p13-p12, 1\n")
        orchlines.append("kvib vibrato kslope*p4%s, p5%s, p6%s, p7%s, p8%s, p9%s, p10%s, p11%s, 1\n" % (amp, freq, amrd, frrd, amin, amax, fmin, fmax))
        orchlines.append("ksig = 1 + kvib\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), _wrap(frequency,i), _wrap(amplituderand,i))
        line += "%s %s %s %s %s " % (_wrap(frequencyrand,i), _wrap(ampminrate,i), _wrap(ampmaxrate,i), _wrap(freqminrate,i), _wrap(freqmaxrate,i))
        line += "%s %s " % (_wrap(delay,i), _wrap(slopedur,i))
        if amplitudeVar: line += '%s ' % _kbusget(_wrap(amplitudeVar,i))
        if frequencyVar: line += '%s ' % _kbusget(_wrap(frequencyVar,i))
        if amplituderandVar: line += '%s ' % _kbusget(_wrap(amplituderandVar,i))
        if frequencyrandVar: line += '%s ' % _kbusget(_wrap(frequencyrandVar,i))
        if ampminrateVar: line += '%s ' % _kbusget(_wrap(ampminrateVar,i))
        if ampmaxrateVar: line += '%s ' % _kbusget(_wrap(ampmaxrateVar,i))
        if freqminrateVar: line += '%s ' % _kbusget(_wrap(freqminrateVar,i))
        if freqmaxrateVar: line += '%s ' % _kbusget(_wrap(freqmaxrateVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'frequency', 'amplituderand', 'frequencyrand', 'ampminrate', 'ampmaxrate', 'freqminrate', 'freqmaxrate']
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if frequencyVar: paramDict[procNum][str(instrument)].append('frequencyVar')
        if amplituderandVar: paramDict[procNum][str(instrument)].append('amplituderandVar')
        if frequencyrandVar: paramDict[procNum][str(instrument)].append('frequencyrandVar')
        if ampminrateVar: paramDict[procNum][str(instrument)].append('ampminrateVar')
        if ampmaxrateVar: paramDict[procNum][str(instrument)].append('ampmaxrateVar')
        if freqminrateVar: paramDict[procNum][str(instrument)].append('freqminrateVar')
        if freqmaxrateVar: paramDict[procNum][str(instrument)].append('freqmaxrateVar')
        _routeScoreline(line)

def jitter(bus, amplitude=1, amp1=0.5, freq1=0.1, amp2=0.2, freq2=1, amp3=.05, 
            freq3=5, starttime=0, duration=None, amplitudeVar=None, amp1Var=None, 
            freq1Var=None, amp2Var=None, freq2Var=None, amp3Var=None, freq3Var=None):
    """Generates a three stages jitter controller.

bus = bus_output
amplitude = 1
amp1 = 0.5
freq1 = 0.1
amp2 = 0.2
freq2 = 1
amp3 = 0.05
freq3 = 5
starttime = 0
duration = None
amplitudeVar = None
amp1Var = None
freq1Var = None
amp2Var = None
freq2Var = None
amp3Var = None
freq3Var = None

--- PARAMETERS ---

bus : Name of the output control bus.
amplitude : Resulting amplitude of jitter.
amp1 : Amplitude of the first jitter component.
freq1 : Speed of random variation of the first jitter component (expressed in cps).
amp2 : Amplitude of the second jitter component.
freq2 : Speed of random variation of the second jitter component (expressed in cps). 
amp3 : Amplitude of the third jitter component.
freq3 : Speed of random variation of the third jitter component (expressed in cps). 
starttime : Starting time of the function performance in seconds.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
amplitudeVar : Name of the control bus multiplying amplitude value.
amp1Var : Name of the control bus multiplying amp1 value.
freq1Var : Name of the control bus multiplying freq1 value.
amp2Var : Name of the control bus multiplying amp2 value.
freq2Var : Name of the control bus multiplying freq2 value.
amp3Var : Name of the control bus multiplying amp3 value.
freq3Var : Name of the control bus multiplying freq3 value.
"""
    if not duration: duration = GDUR
    amp = am1 = fr1 = am2 = fr2 = am3 = fr3 = ''
    bus, duration, starttime, amplitude = _convertToList(bus, duration, starttime, amplitude)
    amp1, freq1, amp2, freq2, amp3, freq3 = _convertToList(amp1, freq1, amp2, freq2, amp3, freq3)
    amplitudeVar, amp1Var, freq1Var, amp2Var, freq2Var, amp3Var, freq3Var = _convertVarToList(amplitudeVar, amp1Var, freq1Var, amp2Var, freq2Var, amp3Var, freq3Var)
    seq = max(len(bus), len(duration), len(starttime), len(amp1), len(amplitude), len(freq1), len(amp2), len(freq2), len(amp3), len(freq3),
              _len(amplitudeVar), _len(amp1Var), _len(freq1Var), _len(amp2Var), _len(freq2Var), _len(amp3Var), _len(freq3Var),)

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("kjit%d jitter2 %s" % (i, i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s" % _wrap(amp1,i))
            if amp1Var:
                orchlines.append("*kbus%s" % _wrap(amp1Var,i))
            orchlines.append(", %s" % _wrap(freq1,i))
            if freq1Var:
                orchlines.append("*kbus%s" % _wrap(freq1Var,i))
            orchlines.append(", %s" % _wrap(amp2,i))
            if amp2Var:
                orchlines.append("*kbus%s" % _wrap(amp2Var,i))
            orchlines.append(", %s" % _wrap(freq2,i))
            if freq2Var:
                orchlines.append("*kbus%s" % _wrap(freq2Var,i))
            orchlines.append(", %s" % _wrap(amp3,i))
            if amp3Var:
                orchlines.append("*kbus%s" % _wrap(amp3Var,i))
            orchlines.append(", %s" % _wrap(freq3,i))
            if freq3Var:
                orchlines.append("*kbus%s" % _wrap(freq3Var,i))
            orchlines.append("\n")
            orchlines.append("kbus%s = 1 + kjit%d\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('jitter', 0, True)
        pval = 11
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')        
        if amp1Var:
            pval, am1 = _setxxxVar(pval, 'am1')
        if freq1Var:
            pval, fr1 = _setxxxVar(pval, 'fr1')        
        if amp2Var:
            pval, am2 = _setxxxVar(pval, 'am2')        
        if freq2Var:
            pval, fr2 = _setxxxVar(pval, 'fr2')        
        if amp3Var:
            pval, am3 = _setxxxVar(pval, 'am3')        
        if freq3Var:
            pval, fr3 = _setxxxVar(pval, 'fr3')        
            
        orchlines.append("kjit jitter2 p4%s, p5%s, p6%s, p7%s, p8%s, p9%s, p10%s\n" % (amp, am1, fr1, am2, fr2, am3, fr3))
        orchlines.append("ksig = 1 + kjit\n")
        orchlines.append('chnset ksig, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), _wrap(amp1,i), _wrap(freq1,i))
        line += "%s %s %s %s " % (_wrap(amp2,i), _wrap(freq2,i), _wrap(amp3,i), _wrap(freq3,i))
        if amplitudeVar: line += '%s ' % _kbusget(_wrap(amplitudeVar,i))
        if amp1Var: line += '%s ' % _kbusget(_wrap(amp1Var,i))
        if freq1Var: line += '%s ' % _kbusget(_wrap(freq1Var,i))
        if amp2Var: line += '%s ' % _kbusget(_wrap(amp2Var,i))
        if freq2Var: line += '%s ' % _kbusget(_wrap(freq2Var,i))
        if amp3Var: line += '%s ' % _kbusget(_wrap(amp3Var,i))
        if freq3Var: line += '%s ' % _kbusget(_wrap(freq3Var,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'amp1', 'freq1', 'amp2', 'freq2', 'amp3', 'freq3']
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if amp1Var: paramDict[procNum][str(instrument)].append('amp1Var')
        if freq1Var: paramDict[procNum][str(instrument)].append('freq1Var')
        if amp2Var: paramDict[procNum][str(instrument)].append('amp2Var')
        if freq2Var: paramDict[procNum][str(instrument)].append('freq2Var')
        if amp3Var: paramDict[procNum][str(instrument)].append('amp3Var')
        if freq3Var: paramDict[procNum][str(instrument)].append('freq3Var')
        _routeScoreline(line)
        
def metro(bus, duration=None, starttime=0, tempo=120, tap=16, tapVar=None, tempoVar=None):
    """Defines and starts a metronome and sends it on a controller bus.

bus = output_bus
starttime = 0
duration = None
tempo = 120 # BPM
tap = 16 # number of beats per bar
tapVar = None
tempoVar = None
"""
    if not duration: duration = GDUR
    ta = tem = ''
    bus, duration, starttime, tempo, tap = _convertToList(bus, duration, starttime, tempo, tap)
    tempoVar, tapVar = _convertVarToList(tempoVar, tapVar)
    seq = max(len(bus), len(tempo), len(tap), len(duration), len(starttime), _len(tapVar), _len(tempoVar))

    if midiSynthesizer:
        for i in range(seq):
            orchlines.append("ktap%d init 0\n" % i)
            if tempoVar:
                orchlines.append("ktrig%d metro %s*kbus%s/15\n" % (i, _wrap(tempo,i), _wrap(tempoVar,i)))
            else:
                orchlines.append("ktrig%d metro %s/15\n" % (i, _wrap(tempo,i)))
            orchlines.append("if ktrig%d == 1 then\n" % i)
            orchlines.append("ktap%d = ktap%d + 1\nendif\n" % (i, i))
            orchlines.append("kbus%s = ktap%d\n" % (_wrap(bus,i), i))
            orchlines.append("if ktap%d > %s" % (i, _wrap(tap,i)))
            if tapVar:
                orchlines.append("*kbus%s then\n" % _wrap(tapVar,i))
            else:
                orchlines.append(" then\n")
            orchlines.append("ktap = 0\nendif\n")
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))
        instrument = _checkInst('metro', 0, True)
        pval = 6
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        orchlines.append("ktap init 0\n")
        if tapVar:
            pval, ta = _setxxxVar(pval, 'ta')        
        if tempoVar:
            pval, tem = _setxxxVar(pval, 'tem')

        orchlines.append("ktrig metro p4%s/15\n" % tem)
        orchlines.append("if ktrig == 1 then\n")
        orchlines.append("ktap = ktap + 1\n")
        orchlines.append('chnset ktap, "kbus%s"\n' % busset)
        orchlines.append("endif\n")
        orchlines.append("if ktap >= int(p5%s) then\n" % ta)
        orchlines.append("ktap = 0\nendif\n")
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        line = "i%s %s %s %s %s " % (str(instrument), _wrap(starttime,i), _wrap(duration,i), _wrap(tempo,i), _wrap(tap,i))
        if tapVar: line += '%s ' % _kbusget(_wrap(tapVar,i))
        if tempoVar: line += '%s ' % _kbusget(_wrap(tempoVar,i))
        line += '\n'
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'tempo', 'tap']
        if tapVar: paramDict[procNum][str(instrument)].append('tapVar')
        if tempoVar: paramDict[procNum][str(instrument)].append('tempoVar')        
        _routeScoreline(line)


###############################################
########### Analysis instruments ##############
def pitchAmp(input, pitchbus, ampbus, duration=None, starttime=0, minfreq=50, maxfreq=500, pitchfilter=1, centralpitch=0, downsamp=1, rate=0):
    """Follows the pitch and amplitude of a signal based on the AMDF (Average Magnitude Difference Function) method. Sends a transposition factor around the centralpitch on pitchbus and an amplitude factor normalized between 0 and 1 on ampbus.


input = input_sound
pitchbus = bus_output_pitch
ampbus = bus_output_amplitude
duration = None
starttime = 0
minfreq = 50
maxfreq = 500
pitchfilter = 1 (0 = no filter)
centralpitch = 1000
downsamp = 1
rate = 0 (0 = minfreq)

--- PARAMETERS ---

input : Name of the audio input channel.
pitchbus : Name of the output control bus for pitch value. Sends a transposition factor around the centralpitch.
ampbus : Name of the output control bus for amplitude value. Amplitude factor are normalized between 0 and 1.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
minfreq : Estimated minimum frequency (expressed in Hz) present in the signal.
maxfreq : Estimated maximum frequency present in the signal.
pitchfilter : Size of median filter applied to the output frequency estimation. The size of the filter will be imedi*2+1. If 0, no median filtering will be applied.
centralpitch : Pitch in Hz corresponding to a transposition factor of 1.
downsamp : Downsampling factor for input signal. Must be an integer. A factor of idowns > 1 results in faster performance, but may result in worse pitch detection. Useful range is 1 - 4.
rate : How frequently pitch analysis is executed, expressed in Hz. If 0, rate is set to minfreq.
"""
    if not duration: duration = GDUR
    starttime, duration, input, pitchbus, ampbus, minfreq, maxfreq = _convertToList(starttime, duration, input, pitchbus, ampbus, minfreq, maxfreq)
    pitchfilter, centralpitch, downsamp, rate = _convertToList(pitchfilter, centralpitch, downsamp, rate)
    seq = max(len(input), len(pitchbus), len(ampbus), len(starttime), len(duration), len(minfreq), len(maxfreq), len(pitchfilter), len(centralpitch), 
                len(downsamp), len(rate))

    if midiSynthesizer:
        for i in range(seq):
            ampScale = math.sqrt(1. / _checkChannels())
            orchlines.append("ain%d = " % i)
            for j in range(_checkChannels()):
                orchlines.append("(abus%s%s * %f)+" % (j, _wrap(input,i), ampScale))
            orchlines.append("0\n")            
            orchlines.append("kanalpit, kanalamp pitchamdf ain%d, %s, %s, 0, %s, %s, %s, 0\n" % (i, _wrap(minfreq,i), _wrap(maxfreq,i), _wrap(pitchfilter,i), _wrap(downsamp,i), _wrap(rate,i)))
            orchlines.append("kbus%s port kanalpit/%s, 0.01\nkbus%s port kanalamp/32768, 0.01\n" % (_wrap(pitchbus,i), _wrap(centralpitch,i), _wrap(ampbus,i)))
        return

    for i in range(seq):
        pbusset = _kbusset(_wrap(pitchbus,i))
        abusset = _kbusset(_wrap(ampbus,i))
        instrument = _checkInst('pitchAmp', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        for j in range(_checkChannels()):
            num = j + 1
            voice = _checkChannels() - num
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
        ampScale = math.sqrt(1. / _checkChannels())
        orchlines.append("ainput = ")
        for j in range(_checkChannels()):
            num = j + 1
            orchlines.append("(ain%d * %f)+" % (num, ampScale))
        orchlines.append("0\n")
        orchlines.append("ainput tone ainput, 1000\n")
        orchlines.append("kpit, kamp pitchamdf ainput, p5, p6, 0, p7, p8, p9, 0\n")
        orchlines.append("kpit2 port kpit/p10, 0.01\n")
        orchlines.append("kamp2 port kamp/32768, 0.01\n")
        orchlines.append('chnset kpit2, "kbus%s"\n' % pbusset)
        orchlines.append('chnset kamp2, "kbus%s"\n' % abusset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)

        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'minfreq', 'maxfreq', 'pitchfilter', 'downsamp', 'rate', 'centralpitch']
        ainput = _zakget(_wrap(input,i))
        line = 'i%s %s %s %s %s %s %s %s %s %s\n' % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(minfreq,i), _wrap(maxfreq,i), _wrap(pitchfilter,i), _wrap(downsamp,i), _wrap(rate,i), _wrap(centralpitch,i))
        _routeScoreline(line)
 
def centroid(input, bus, duration=None, starttime=0, fftsize=1024, overlaps=4, windowsize=2048):
    """Follows the spectral centroid of a signal. Sends a control signal between 0 and 1 (1 == sr/2). 

input = input_sound
bus = bus_output
duration = None
starttime = 0
fftsize = 1024
overlaps = 4
windowsize = 2048

--- PARAMETERS ---

input : Name of the audio input channel.
bus : Name of the output control bus.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
fftsize : The FFT size in samples. Power of two are most efficient sizes. fftsize determines the number of analysis bins, as fftsize/2 + 1.
overlaps : Used to calculate the distance in samples (hop size) between overlapping analysis frames.
windowsize : The size in samples of the analysis window filter. This must be at least fftsize, and can usefully be larger.
"""
    if not duration: duration = GDUR
    bus, starttime, duration, input, fftsize, overlaps, windowsize = _convertToList(bus, starttime, duration, input, fftsize, overlaps, windowsize)
    seq = max(len(input), len(bus), len(starttime), len(duration), len(fftsize), len(overlaps), len(windowsize))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            ampScale = math.sqrt(1. / _checkChannels())
            orchlines.append("ain%d = " % i)
            for j in range(_checkChannels()):
                orchlines.append("(abus%s%s * %f)+" % (j, _wrap(input,i), ampScale))
            orchlines.append("0\n")            
            orchlines.append("fsig%d pvsanal ain%d, %s, %s/%s, %s, 1\n" % (i, i, _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
            orchlines.append("kcentroid pvscent fsig%d\n" % i)
            orchlines.append("kbus%s port kcentroid/(%s/2), 0.01\n" % (_wrap(bus,i), sr))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))    
        instrument = _checkInst('centroid', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        for j in range(_checkChannels()):
            num = j + 1
            voice = _checkChannels() - num
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
        ampScale = math.sqrt(1. / _checkChannels())
        orchlines.append("ainput = ")
        for j in range(_checkChannels()):
            num = j + 1
            orchlines.append("(ain%d * %f)+" % (num, ampScale))
        orchlines.append("0\n")
        orchlines.append("fsig pvsanal ainput, p5, p5/p6, p7, 1\n")
        orchlines.append("kcentroid pvscent fsig\n")
        orchlines.append("kcentroid2 port kcentroid/(%s/2), 0.01\n" % sr)
        orchlines.append('chnset kcentroid2, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)        
        
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'fftsize', 'overlaps', 'windowsize']

        ainput = _zakget(_wrap(input,i))
        line = 'i%s %s %s %s %s %s %s\n' % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i))
        _routeScoreline(line)

def rms(input, bus, duration=None, starttime=0, lowpass=10):
    """Follows root-mean-square amplitude of a signal. Sends a control signal normalized between 0 and 1. 

input = input_sound
bus = bus_output
duration = None
starttime = 0
lowpass = 10

--- PARAMETERS ---

input : Name of the audio input channel.
bus : Name of the output control bus.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
lowpass : Cutoff of a lowpass filter applied on input signal.
""" 
    if not duration: duration = GDUR
    bus, starttime, duration, input, lowpass = _convertToList(bus, starttime, duration, input, lowpass)
    seq = max(len(input), len(bus), len(starttime), len(duration), len(lowpass))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            ampScale = math.sqrt(1. / _checkChannels())
            orchlines.append("ain%d = " % i)
            for j in range(_checkChannels()):
                orchlines.append("(abus%s%s * %f)+" % (j, _wrap(input,i), ampScale))
            orchlines.append("0\n")            
            orchlines.append("krms%d rms ain%d, %s\n" % (i, i, _wrap(lowpass,i)))
            orchlines.append("kbus%s port krms%d/32768, 0.01\n" % (_wrap(bus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(bus,i))    
        instrument = _checkInst('rms', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        for j in range(_checkChannels()):
            num = j + 1
            voice = _checkChannels() - num
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
        ampScale = math.sqrt(1. / _checkChannels())
        orchlines.append("ainput = ")
        for j in range(_checkChannels()):
            num = j + 1
            orchlines.append("(ain%d * %f)+" % (num, ampScale))
        orchlines.append("0\n")
        orchlines.append("krms rms ainput, p5\n")
        orchlines.append("krms2 port krms/32768, 0.01\n")
        orchlines.append('chnset krms2, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)        
        
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'lowpass']

        ainput = _zakget(_wrap(input,i))
        line = 'i%s %s %s %s %s\n' % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(lowpass,i))
        _routeScoreline(line)

def attackDetector(input, trigbus, duration=None, starttime=0, lowpass=10, response=.01, attackthresh=-6, minthresh=-50, releasethresh=.4, releasetime=.25):
    """Attack detector. Sends a trigger control signal on trigbus. 

input = input_sound
trigbus = bus_output
duration = None
starttime = 0
lowpass = 10
response = 0.01
attackthresh = -6
minthresh = -50
releasethresh = 0.4
releasetime = 0.25

--- PARAMETERS ---

input : Name of the audio input channel.
trigbus : Name of the output control bus.
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
lowpass : Cutoff, in hertz, of a lowpass filter applied on input signal.
response : Response time in seconds (attack time).
attackthresh : Attack threshold in dB. Trigger signal is send when rms amplitude of input signal exceed this threshold.
minthresh : Minimum dB level before detecting attack. rms amplitude of input signal must go down below this threshold to enable a new detection.
releasethresh : Release threshold, as fraction of attack rms amplitude.
releasetime : Release delay time, time to wait after signal have dropped below threshold.

* Based on an orchestra by Oeyvind Brandtsegg
""" 

    if not duration: duration = GDUR
    trigbus, starttime, duration, input, lowpass = _convertToList(trigbus, starttime, duration, input, lowpass)
    response, attackthresh, minthresh, releasethresh, releasetime = _convertToList(response, attackthresh, minthresh, releasethresh, releasetime)
    seq = max(len(input), len(trigbus), len(starttime), len(duration), len(lowpass), len(response), len(attackthresh),
              len(minthresh), len(releasethresh), len(releasetime))

    if not 'attackDetector' in UDO:
        UDO.append('attackDetector')
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            ampScale = math.sqrt(1. / _checkChannels())
            orchlines.append("ain%d = " % i)
            for j in range(_checkChannels()):
                orchlines.append("(abus%s%s * %f)+" % (j, _wrap(input,i), ampScale))
            orchlines.append("0\n")            
            orchlines.append("ktrigger%d attackDetector ain%d, %s, %s, %s, %s, %s, %s\n" % (i, i, _wrap(response,i), _wrap(attackthresh,i), _wrap(minthresh,i), _wrap(releasethresh,i), _wrap(releasetime,i), _wrap(lowpass,i)))
            orchlines.append("kbus%s = ktrigger%d\n" % (_wrap(trigbus,i), i))
        return

    for i in range(seq):
        busset = _kbusset(_wrap(trigbus,i))    
        instrument = _checkInst('attackDetector', 0, True)
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        for j in range(_checkChannels()):
            num = j + 1
            voice = _checkChannels() - num
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
        ampScale = math.sqrt(1. / _checkChannels())
        orchlines.append("ainput = ")
        for j in range(_checkChannels()):
            num = j + 1
            orchlines.append("(ain%d * %f)+" % (num, ampScale))
        orchlines.append("0\n")
        orchlines.append("ktrigger attackDetector ainput, p6, p7, p8, p9, p10, p5\n")
        orchlines.append('chnset ktrigger, "kbus%s"\n' % busset)
        orchlines.append("endin\n\n")
        instrlist.append(instrument)        
        
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'lowpass', 'response', 'attackthresh', 'minthresh', 'releasethresh', 'releasetime']

        ainput = _zakget(_wrap(input,i))
        line = 'i%s %s %s %s %s %s %s %s %s %s\n' % (str(instrument), _wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(lowpass,i), _wrap(response,i), _wrap(attackthresh,i), _wrap(minthresh,i), _wrap(releasethresh,i), _wrap(releasetime,i))
        _routeScoreline(line)


######################### Source instruments ############################
###################################################
############# Simple wave instruments #############
def sine(pitch=1000, amplitude=0.7, duration=None, starttime=0, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Plays a sine wave.

pitch = 1000
amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
envelope : Envelope number, returned by genTables functions.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    _play(pitch, amplitude, duration, starttime, pan, envelope, pitchVar, amplitudeVar, panVar, 1, out, 'sine')

def square(pitch=1000, amplitude=0.7, duration=None, starttime=0, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Plays a square wave.

pitch = 1000
amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
envelope : Envelope number, returned by genTables functions.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    _play(pitch, amplitude, duration, starttime, pan, envelope, pitchVar, amplitudeVar, panVar, 2, out, 'square')

def sawtooth(pitch=1000, amplitude=0.7, duration=None, starttime=0, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Plays a sawtooth wave.

pitch = 1000
amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
envelope : Envelope number, returned by genTables functions.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    _play(pitch, amplitude, duration, starttime, pan, envelope, pitchVar, amplitudeVar, panVar, 3, out, 'sawtooth')

def waveform(pitch=1000, amplitude=0.7, duration=None, starttime=0, pan=0.5, envelope=None, table='default', pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Plays a composite waveform (usually generated by genWaveform).

pitch = 1000
amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
table = 'default' # or table generated with genWaveform function
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
table : Number of the waveform table returned by genTables functions.
envelope : Envelope number, returned by genTables functions.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = "Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    if table == 'default': wavetable = 10
    else: wavetable = table
    _play(pitch, amplitude, duration, starttime, pan, envelope, pitchVar, amplitudeVar, panVar, wavetable, out, 'waveform')

def _play( pitch, amplitude, duration, starttime, pan, envelope, pitchVar, amplitudeVar, panVar, table, out, inst):
    ipanpval = outpval = 0
    env = pit = amp = panval = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, table = _convertToList(pitch, amplitude, starttime, duration, pan, table)
    envelope, pitchVar, amplitudeVar, panVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(table), _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("a0%d oscili 32000*%s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s*kpit" % _wrap(pitch,i))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", %s\n" % _wrap(table,i))
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst(inst, int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 oscili 32000*p5%s%s, p4%s, p6, -1\n" % (env, amp, pit))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'table']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % instrument
        line += "%s %s %s %s %s " % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(table,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


######################################################
########### Complex source instruments ###############
# need a big clean up!
def soundfont(sf2='piano.SF2', midipitch=48, amplitude=1, duration=None, starttime=0, pan=0.5,
              channel=1, bank=0, preset=0, amplitudeVar=None, panVar=None, out='dac'):
    """A soundfont player.

sf2 = 'piano.SF2'
midipitch = 48
amplitude = 1
duration = None
starttime = 0
pan = 0.5
channel = 1
bank = 0
preset = 0
amplitudeVar = None
panVar = None
out = 'dac'"""
    global insideSoundfont
    insideSoundfont = True
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    sf2, midipitch, amplitude, starttime, duration, pan, channel, bank, preset = _convertToList(sf2, midipitch, amplitude, starttime,
                                                                                                duration, pan, channel, bank, preset)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(midipitch), len(amplitude), len(starttime), len(duration), len(pan))
    seq1 = max(len(sf2), len(channel), len(bank), len(preset), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        raise Error("Use soundfontMidi instead of soundfont inside a midi synth")
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    inst1 = []
    for i in range(seq1):
        instrument1 = _checkInst('soundfont', 0, True)
        instrument2 = _checkInst('', 0, True)
        pval = 4
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        
        fullfont = None
        if os.path.isfile(_wrap(sf2,i)):
            fullfont = _wrap(sf2,i)
        elif project_paths:
            for path in project_paths:
                if os.path.isfile(os.path.join(path, _wrap(sf2,i))):
                    fullfont = os.path.join(path, _wrap(sf2,i))
                    break
        if not fullfont:
            fullfont = os.path.join(soundfont_path, _wrap(sf2,i))

        inst1.append(fullfont)
            
        if not fullfont in soundfontsUsed.keys():
            soundfontsUsed[fullfont] = {offset: instrument1}
            soundfontlines.append("giengine%d fluidEngine\n" % instrument1)
            soundfontlines.append('isfnum%d fluidLoad "%s", giengine%d, 1\n' % (instrument1, fullfont, instrument1))
            soundfontlines.append("fluidProgramSelect giengine%d, 1, isfnum%d, %s, %s\n" % (instrument1, instrument1, _wrap(bank,i), _wrap(preset,i)))
            soundfontlines.append("massign %d, %d\n" % (_wrap(channel,i), instrument1))
            soundfontlines.append("turnon %d\n" % instrument1)

            orchlines.append("instr %d\n" % instrument1)
            orchlines.append("mididefault 20, p3\n")
            orchlines.append("midinoteonkey p4, int(p5*127)\n")
            orchlines.append("fluidNote giengine%d, 1, p4, int(p5*127)\n" % instrument1)
            orchlines.append("endin\n\n")
            orchlines.append("instr %d\n" % instrument2)
            orchlines.append("a0, a1 fluidOut giengine%d \n" % instrument1)
            orchlines.append("a0 = a0*32768%s\na1 = a1*32768%s\n" % (amp, amp))
            _outPanSig(out, outpval, ipanpval, panval, 2, _checkChannels())

            if _wrap(duration,i) < 0: line = "i%s " % str(instrument2 + _infinite())
            else: line = "i%s " % instrument2
            line += "%s -1 " % (_wrap(starttime,i))
            if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
            if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
            if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
            if out != 'dac': line += "%s" % out
            line += "\n"
            if sequencer:
                paramDict[procNum][str(instrument2)] = ['starttime', 'duration']
                if _checkChannels() > 1:
                    paramDict[procNum][str(instrument2)].append('pan')
                _formatSeqScore(line)
            else:
                scorelines.append(line)
        elif not offset in soundfontsUsed[fullfont].keys():
            soundfontsUsed[fullfont][offset] = instrument1
            soundfontlines.append("giengine%d fluidEngine\n" % instrument1)
            soundfontlines.append('isfnum%d fluidLoad "%s", giengine%d, 1\n' % (instrument1, fullfont, instrument1))
            soundfontlines.append("fluidProgramSelect giengine%d, 1, isfnum%d, %s, %s\n" % (instrument1, instrument1, _wrap(bank,i), _wrap(preset,i)))
            soundfontlines.append("massign %d, %d\n" % (_wrap(channel,i), instrument1))
            soundfontlines.append("turnon %d\n" % instrument1)

            orchlines.append("instr %d\n" % instrument1)
            orchlines.append("mididefault 20, p3\n")
            orchlines.append("midinoteonkey p4, int(p5*127)\n")
            orchlines.append("fluidNote giengine%d, 1, p4, int(p5*127)\n" % instrument1)
            orchlines.append("endin\n\n")
            orchlines.append("instr %d\n" % instrument2)
            orchlines.append("a0, a1 fluidOut giengine%d \n" % instrument1)
            orchlines.append("a0 = a0*32768%s\na1 = a1*32768%s\n" % (amp, amp))
            _outPanSig(out, outpval, ipanpval, panval, 2, _checkChannels())

            if _wrap(duration,i) < 0: line = "i%s " % str(instrument2 + _infinite())
            else: line = "i%s " % instrument2
            line += "%s -1 " % (_wrap(starttime,i))
            if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
            if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
            if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
            if out != 'dac': line += "%s" % out
            line += "\n"
            if sequencer:
                paramDict[procNum][str(instrument2)] = ['starttime', 'duration']
                if _checkChannels() > 1:
                    paramDict[procNum][str(instrument2)].append('pan')
                _formatSeqScore(line)
            else:
                scorelines.append(line)
                
    for i in range(seq):
        inst = soundfontsUsed[_wrap(inst1,i)][offset]
        if _wrap(duration,i) < 0: line = "i%s " % str(inst + _infinite())
        else: line = "i%s " % inst
        line += "%s %s %s %s\n" % (_wrap(starttime,i), _wrap(duration,i), _wrap(midipitch,i), _wrap(amplitude,i))
        paramDict[procNum][str(inst)] = ['starttime', 'duration', 'midipitch', 'amplitude']
        _routeScoreline(line)

# not up to date with loops and pythonInst
def soundfontMidi(sf2='piano.SF2', amplitude=1, duration=None, starttime=0, pan=0.5,
              channel=1, bank=0, preset=0, amplitudeVar=None, panVar=None, out='dac'):
    """A soundfont player for use with a midi controller.

sf2 = 'piano.SF2'
amplitude = 1
duration = None
starttime = 0
pan = 0.5
channel = 1
bank = 0
preset = 0
amplitudeVar = None
panVar = None
out = 'dac'"""
    global insideSoundfont, midi
    insideSoundfont = True
    midi = '-M%d ' % mididev
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    sf2, amplitude, starttime, duration, pan, channel, bank, preset = _convertToList(sf2, amplitude, starttime,
                                                                                           duration, pan, channel, bank, preset)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(sf2), len(amplitude), len(starttime), len(duration), len(pan), len(channel), len(bank), len(preset), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        raise Error("Already a Midi instrument")
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    for i in range(seq):
        instrument1 = _checkInst('soundfontMidi', 0)
        instrument2 = _checkInst('soundfontMidi', 0)
        pval = 4
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval

        fullfont = None
        if os.path.isfile(_wrap(sf2,i)):
            fullfont = _wrap(sf2,i)
        elif project_paths:
            for path in project_paths:
                if os.path.isfile(os.path.join(path, _wrap(sf2,i))):
                    fullfont = os.path.join(path, _wrap(sf2,i))
                    break
        if not fullfont:
            fullfont = os.path.join(soundfont_path, _wrap(sf2,i))

        soundfontlines.append("giengine%d  fluidEngine\n" % instrument1)
        soundfontlines.append('isfnum%d    fluidLoad "%s", giengine%d, 1\n' % (instrument1, fullfont, instrument1))
        soundfontlines.append("fluidProgramSelect giengine%d, 1, isfnum%d, %s, %s\n" % (instrument1, instrument1, _wrap(bank,i), _wrap(preset,i)))
        soundfontlines.append("massign %d, %d\n" % (_wrap(channel,i), instrument1))
        soundfontlines.append("turnon %d\n" % instrument1)

        orchlines.append("instr %d\n" % instrument1)
        orchlines.append("kstatus, kchan, kdata1, kdata2 midiin\n")
        orchlines.append("fluidControl     giengine%d, kstatus, kchan, kdata1, kdata2\n" % instrument1)
        orchlines.append("endin\n\n")
        orchlines.append("instr %d\n" % instrument2)
        orchlines.append("a0, a1 fluidOut   giengine%d \n" % instrument1)
        orchlines.append("a0 = a0*32768*%d%s\na1 = a1*32768*%d%s\n" % (_wrap(amplitude,i), amp, _wrap(amplitude,i), amp))
        _outPanSig(out, outpval, ipanpval, panval, 2, _checkChannels())

        if _wrap(duration,i) < 0: line = "i%s " % str(instrument2 + _infinite())
        else: line = "i%s " % instrument2
        line += "%s %s " % (_wrap(starttime,i), _wrap(duration,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        if not sequencer:
            scorelines.append(line)
        else:
            paramDict[procNum][str(instrument)] = ['starttime', 'duration']
            if _checkChannels() > 1:
                paramDict[procNum][str(instrument)].append('pan')
            _formatSeqScore(line)

def playSound(sound='ounkmaster.aif', pitch=1, amplitude=1, loop=False, duration=None, starttime=0, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Plays a sound file directly from disk.

sound = 'ounkmaster.aif'
pitch = 1
amplitude = 1
loop = False
duration = None
starttime = 0
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

sound : String denoting the source soundfile name. If not a full pathname, the named file is sought in the default sound_path directory.
pitch : Transpose the pitch of input sound by this factor (e.g. 0.5 means one octave lower, 2 is one octave higher, and 1 is the original pitch). Fractional values are allowed.
amplitude : Amplitude (1 is nominal amplitude).
loop : Boolean. If True the file will be played in loop.
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
envelope : Envelope number, returned by genTables functions.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar]
    sound, pitch, amplitude, loop, starttime, duration, pan = _convertToList(sound, pitch, amplitude, loop, starttime, duration, pan)
    envelope, pitchVar, amplitudeVar, panVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar)
    seq = max(len(sound), len(pitch), len(amplitude), len(loop), len(starttime), len(duration), len(pan), _len(envelope), _len(pitchVar),
                _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            fullname = None
            if os.path.isfile(_wrap(sound,i)):
                fullname = _wrap(sound,i)
            elif project_paths:
                for path in project_paths:
                    if os.path.isfile(os.path.join(path, _wrap(sound,i))):
                        fullname = os.path.join(path, _wrap(sound,i))
                        break
            if not fullname:
                fullname = os.path.join(sound_path, _wrap(sound,i))
            if _wrap(loop,i) == False: lp = 0
            else: lp = 1
            channels = getSoundInfo(_wrap(sound,i))[0]
            orchlines.append(', '.join(['a%d%d' % (j,i) for j in range(channels)]) + ' diskin2 "%s", %s*kpit' % (fullname, _wrap(pitch,i)))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", 0, %s\n" % str(lp))
            for j in range(channels):
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, channels, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    for i in range(seq):
        instrument = _checkInst('playSound', int(_whichVars(vars) + offset + (100 * _checkChannels())))
        pval = 8
        if not instrument in instrlist:
            orchlines.append("instr %d\n" % instrument)
            if _checkChannels() > 1:
                ipanpval, pval = _setpan(pval)
            if envelope:
                pval, env = _setenvelope(pval)
            if pitchVar:
                pval, pit = _setxxxVar(pval, 'pit')
            if amplitudeVar:
                pval, amp = _setxxxVar(pval, 'amp')
            if panVar:
                pval, panval = _setpanVar(pval)
            if out != 'dac':
                outpval = pval
            instrlist.append(instrument)

            channels = getSoundInfo(_wrap(sound,i))[0]
            
            if triggeredInst: 
                orchlines.append(', '.join(['a%d' % j for j in range(channels)]) + ' diskin p6, p4%s, 0, p7\n' % pit)
            else:    
                orchlines.append(', '.join(['a%d' % j for j in range(channels)]) + ' diskin2 p6, p4%s, 0, p7\n' % pit)
            for j in range(channels):
                orchlines.append("a%d = a%d * p5%s%s\n" % ((j, j, env, amp)))
            _outPanSig(out, outpval, ipanpval, panval, channels, _checkChannels())
            
        fullname = None
        if os.path.isfile(_wrap(sound,i)):
            fullname = _wrap(sound,i)
        elif project_paths:
            for path in project_paths:
                if os.path.isfile(os.path.join(path, _wrap(sound,i))):
                    fullname = os.path.join(path, _wrap(sound,i))
                    break
        if not fullname:
            fullname = os.path.join(sound_path, _wrap(sound,i))
        
        if sequencer or triggeredInst:
            fullname = _setStringSet(fullname)
            
        if _wrap(loop,i) == False: lp = 0
        else: lp = 1
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        if sequencer or triggeredInst:
            line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), fullname, lp)
        else:
            line += '%s %s %s %s "%s" %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), fullname, lp)
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'sound', 'loop']
        if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
        if envelope: paramDict[procNum][str(instrument)].append('envelope')
        if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if panVar: paramDict[procNum][str(instrument)].append('panVar')
        _routeScoreline(line)

def inputMic(amplitude=1, starttime=0, duration=None, channel=1, pan=0.5, amplitudeVar=None, panVar=None, out='dac'):
    """Retreives sound from a microphone input.

amplitude = 1
duration = None
starttime = 0
pan = 0.5
channel = 1 # input channel
amplitudeVar = None
panVar = None
out = 'dac'"""

    global inadc
    inadc = '-iadc'
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, channel, pan = _convertToList(amplitude, starttime, duration, channel, pan)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(channel), len(amplitude), len(starttime), len(duration), len(pan), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("a0%d inch %s\n" % (i, _wrap(channel,i)))
            orchlines.append("a0%d = a0%d*%s" % (i, i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
            else: orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('inputMic', int(_whichVars(vars) + offset))
    pval = 6
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 inch p4\n")
        orchlines.append("a0 = a0*p5%s\n" % amp)
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'channel', 'amplitude']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(channel,i), _wrap(amplitude,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
    
def whiteNoise(amplitude=0.7, starttime=0, duration=None, pan=0.5, envelope=None, amplitudeVar=None, panVar=None, out='dac'):
    """Generates white noise.

amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
envelope = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = amp = panval = ''
    vars = [envelope, amplitudeVar, panVar]
    amplitude, starttime, duration, pan = _convertToList(amplitude, starttime, duration, pan)
    envelope, amplitudeVar, panVar = _convertVarToList(envelope, amplitudeVar, panVar)
    seq = max(len(amplitude), len(starttime), len(duration), len(pan), _len(envelope), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            if amplitudeVar:
                orchlines.append("a0%d rand 32000*%s*kbus%s, 2, 1\n" % (i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
            else:
                orchlines.append("a0%d rand 32000*%s, 2, 1\n" % (i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = 1
    instrument = _checkInst('whiteNoise', offset)
    pval = 5
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 rand 32000*p4%s%s, 2, 1\n" % (env, amp))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def pinkNoise(amplitude=0.7, starttime=0, duration=None, pan=0.5, envelope=None, amplitudeVar=None, panVar=None, out='dac'):
    """Generates pink noise.

amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
envelope = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = amp = panval = ''
    vars = [envelope, amplitudeVar, panVar]
    amplitude, starttime, duration, pan = _convertToList(amplitude, starttime, duration, pan)
    envelope, amplitudeVar, panVar = _convertVarToList(envelope, amplitudeVar, panVar)
    seq = max(len(amplitude), len(starttime), len(duration), len(pan), _len(envelope), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            if amplitudeVar:
                orchlines.append("a0%d pinkish 32000*%s*kbus%s\n" % (i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
            else:
                orchlines.append("a0%d pinkish 32000*%s\n" % (i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = 1
    instrument = _checkInst('pinkNoise', offset)
    pval = 5
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 pinkish 32000*p4%s%s\n" % (env, amp))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def pluckedString(pitch=100, amplitude=0.7, duration=None, starttime=0, cutoff=6000, pan=0.5, pitchVar=None, amplitudeVar=None, panVar=None, cutoffVar=None, out='dac'):
    """Plays the physical model of a string sound.

pitch = 100
amplitude = 0.7
duration = None
starttime = 0
cutoff = 6000
pan = 0.5
pitchVar = None
amplitudeVar = None
panVar = None
cutoffVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Cutoff frequency of a lowpass filter applied on string model output.
pan : Position value between 0 and 1.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
cutoffVar : Name of the control bus multiplying cutoff value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = cut = ''
    vars = [pitchVar, amplitudeVar, panVar, cutoffVar]
    pitch, amplitude, starttime, duration, pan, cutoff = _convertToList(pitch, amplitude, starttime, duration, pan, cutoff)
    pitchVar, amplitudeVar, panVar, cutoffVar = _convertVarToList(pitchVar, amplitudeVar, panVar, cutoffVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(cutoffVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("a0%d pluck 32000*%s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s*kpit" % _wrap(pitch,i))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", 20, 0, 6\na0%d butterlp a0%d, %s" % (i, i, _wrap(cutoff,i)))
            if cutoffVar:
                orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
            else:
                orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('pluckedString', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 pluck 32000*p5%s, p4%s, 20, 0, 6\na0 butterlp a0, p6%s\n" % (amp, pit, cut))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'cutoff']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += "%s %s %s %s %s " % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(cutoff,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def freqMod(pitch=500, amplitude=0.7, duration=None, starttime=0, pan=0.5, carrier=1, modulator=.5, index=5, table='default', envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, carrierVar=None, modulatorVar=None, indexVar=None, out='dac'):
    """Plays a frequency modulation synthesis sound.

pitch = 500
amplitude = 0.7
duration = None
starttime = 0
carrier = 1
modulator = 0.5
index = 5
table = 'default'
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
carrierVar = None
modulatorVar = None
indexVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = car = mod = ind = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar, carrierVar, modulatorVar, indexVar]
    pitch, amplitude, starttime, duration, pan, table, carrier, modulator, index = _convertToList(pitch, amplitude, starttime,
                                                                                    duration, pan, table, carrier, modulator, index)
    envelope, pitchVar, amplitudeVar, panVar, carrierVar, modulatorVar, indexVar = _convertVarToList(envelope, pitchVar, amplitudeVar,
                                                                                    panVar, carrierVar, modulatorVar, indexVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(table), len(carrier), len(modulator), len(index),
              _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(carrierVar), _len(modulatorVar), _len(indexVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            if _wrap(table,i) == 'default': wave = str(1)
            else: wave = _wrap(table,i)
            orchlines.append("a0%d foscili 32000*%s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s*kpit" % _wrap(pitch,i))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", %s" % _wrap(carrier,i))
            if carrierVar:
                orchlines.append("*kbus%s" % _wrap(carrierVar,i))
            orchlines.append(", %s" % _wrap(modulator,i))
            if modulatorVar:
                orchlines.append("*kbus%s" % _wrap(modulatorVar,i))
            orchlines.append(", %s" % _wrap(index,i))
            if indexVar:
                orchlines.append("*kbus%s" % _wrap(indexVar,i))
            orchlines.append(", %s\n" % wave)
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('freqMod', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if carrierVar:
            pval, car = _setxxxVar(pval, 'car')
        if modulatorVar:
            pval, mod = _setxxxVar(pval, 'mod')
        if indexVar:
            pval, ind = _setxxxVar(pval, 'ind')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)
        orchlines.append("a0 foscili 32000*p5%s%s, p4%s, p6%s, p7%s, p8%s, p9\n" % (env, amp, pit, car, mod, ind))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'carrier', 'modulator', 'index', 'table']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar') 
    if carrierVar: paramDict[procNum][str(instrument)].append('carrierVar')
    if modulatorVar: paramDict[procNum][str(instrument)].append('modulatorVar')
    if indexVar: paramDict[procNum][str(instrument)].append('indexVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(carrier,i), _wrap(modulator,i), _wrap(index,i))
        if _wrap(table,i) == 'default': wave = str(1)
        else: wave = _wrap(table,i)
        line += "%s " % wave
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if carrierVar: line += "%s " % _kbusget(_wrap(carrierVar,i))
        if modulatorVar: line += "%s " % _kbusget(_wrap(modulatorVar,i))
        if indexVar: line += "%s " % _kbusget(_wrap(indexVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def bell(pitch=500, amplitude=0.7, duration=None, starttime=0, pan=0.5, vibratoamp=0.005, vibratofreq=6, index=5, pitchVar=None, amplitudeVar=None, panVar=None, vibratoampVar=None, vibratofreqVar=None, indexVar=None, out='dac'):
    """Plays a frequency modulation synthesis sound emulating a tubular bell.

pitch = 500
amplitude = 0.7
duration = None
starttime = 0
pan = 0.5
vibratoamp = 0.005
vibratofreq = 6
index = 5
pitchVar = None
amplitudeVar = None
panVar = None
vibratoampVar = None
vibratofreqVar = None
indexVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Fundamental frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds. Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
vibratoamp : Vibrato amplitude.
vibratofreq : Vibrato frequency in cycle per seconds.
index : Modulation index. Controls the brightness of the sound.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
vibratoampVar : Name of the control bus multiplying vibratoamp value.
vibratofreqVar : Name of the control bus multiplying vibratofreq value.
indexVar : Name of the control bus multiplying index value.
out = "Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = via = vif = ind = ''
    vars = [pitchVar, amplitudeVar, panVar, vibratoampVar, vibratofreqVar, indexVar]
    pitch, amplitude, starttime, duration, pan, vibratoamp, vibratofreq, index = _convertToList(pitch, amplitude, starttime,
                                                                                    duration, pan, vibratoamp, vibratofreq, index)
    pitchVar, amplitudeVar, panVar, vibratoampVar, vibratofreqVar, indexVar = _convertVarToList(pitchVar, amplitudeVar,
                                                                                    panVar, vibratoampVar, vibratofreqVar, indexVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(vibratoamp), len(vibratofreq), len(index),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(vibratoampVar), _len(vibratofreqVar), _len(indexVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("a0%d fmbell 32000*%s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s*kpit" % _wrap(pitch,i))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            if not indexVar:
                orchlines.append(", %s, %s" % (_wrap(index,i), _wrap(index,i)))
            else:    
                orchlines.append(", %s*kbus%s, %s*kbus%s" % (_wrap(index,i), _wrap(indexVar,i), _wrap(index,i), _wrap(indexVar,i)))
            orchlines.append(", %s" % _wrap(vibratoamp,i))
            if vibratoampVar:
                orchlines.append("*kbus%s" % _wrap(vibratoampVar,i))
            orchlines.append(", %s" % _wrap(vibratofreq,i))
            if vibratofreqVar:
                orchlines.append("*kbus%s, 1, 1, 1, 1, 1\n" % _wrap(vibratofreqVar,i))
            else:
                orchlines.append(", 1, 1, 1, 1, 1\n")
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('bell', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if vibratoampVar:
            pval, via = _setxxxVar(pval, 'via')
        if vibratofreqVar:
            pval, vif = _setxxxVar(pval, 'vif')
        if indexVar:
            pval, ind = _setxxxVar(pval, 'ind')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)
        orchlines.append("a0 fmbell 32000*p5%s, p4%s, p8%s, p8%s, p6%s, p7%s, 1, 1, 1, 1, 1\n" % (amp, pit, ind, ind, via, vif))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'vibratoamp', 'vibratofreq', 'index']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar') 
    if vibratoampVar: paramDict[procNum][str(instrument)].append('vibratoampVar')
    if vibratofreqVar: paramDict[procNum][str(instrument)].append('vibratofreqVar')
    if indexVar: paramDict[procNum][str(instrument)].append('indexVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(vibratoamp,i), _wrap(vibratofreq,i), _wrap(index,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if vibratoampVar: line += "%s " % _kbusget(_wrap(vibratoampVar,i))
        if vibratofreqVar: line += "%s " % _kbusget(_wrap(vibratofreqVar,i))
        if indexVar: line += "%s " % _kbusget(_wrap(indexVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
     
def voiceSynth(pitch=100, amplitude=1, duration=None, starttime=0, pan=0.5, consonant=0, vowel=0, voicetype=0, fadein=0.005,
                fadeout=0.1, vowelarticulation=1, consonantarticulation=1, pitchglissando=0.02, vowelglissando=0.02, roughness=0.1,
                formantresonance=1, brilliance=1, glotalresonance=0.5, vibratoamp=0.015, vibratospeed=5.3, voicenumber=None, panVar=None, out='dac'):
    """Plays a source-filter synthesized vocal sound.

pitch = 100
amplitude = 1
duration = None
starttime = 0
pan = 0.5
consonant = 0 # 0 -> 20
vowel = 0 # 0 -> 15
voicetype = 0 # 0 -> 3
fadein = 0.005
fadeout = 0.1
vowelarticulation = 1
consonantarticulation = 1
pitchglissando = 0.02
vowelglissando = 0.02
roughness = 0.1 # 0 -> 1
formantresonance = 1 # 0.1 -> 2
brilliance = 1 # 0.5 -> 1.2
glotalresonance = 0.5 # 0 -> 1
vibratoamp = 0.015
vibratospeed = 5.3 # (Hertz)
voicenumber = None
panVar = None
out = 'dac'

Assign different voicenumber to different notes to play several voices at the same time"""
    global voiceSynthesis, voiceTables
    voiceSynthesis = True
    voiceTables = True
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    panval = ''
    vars = [panVar]
    pitch, amplitude, starttime, duration, pan, consonant, vowel, voicetype, fadein, fadeout = _convertToList(pitch, amplitude, starttime,
                                                                            duration, pan, consonant, vowel, voicetype, fadein, fadeout)
    vowelarticulation, consonantarticulation, pitchglissando, vowelglissando, roughness = _convertToList(vowelarticulation,
                                                                        consonantarticulation, pitchglissando, vowelglissando, roughness)
    formantresonance, brilliance, glotalresonance, vibratoamp, vibratospeed , voicenumber = _convertToList(formantresonance, brilliance, glotalresonance, vibratoamp, vibratospeed, voicenumber)
    panVar = _convertVarToList(panVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(consonant), len(vowel), len(voicetype),
            len(fadein), len(fadeout), len(vowelarticulation), len(consonantarticulation), len(pitchglissando), len(vowelglissando),
            len(roughness), len(formantresonance), len(brilliance), len(glotalresonance), len(vibratoamp), len(vibratospeed), len(voicenumber), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("iCps init %s\n" % _wrap(pitch,i))
            orchlines.append("kCps = %s*kpit\n" % _wrap(pitch,i))
            orchlines.append("iAbsTime = abs(%s)\n" % _wrap(duration,i))
            orchlines.append("iNoteAmplitude init %s\n" % _wrap(amplitude,i))
            orchlines.append("iConsonant init %s*4\n" % _wrap(consonant,i))
            orchlines.append("iTransiTime init %s*6\n" % _wrap(consonant,i))
            orchlines.append("iConsNoiseValues init %s*5\n" % _wrap(consonant,i))
            orchlines.append("iConsEachFormant init %s*6\n" % _wrap(consonant,i))
            orchlines.append("iVowel init %s*4\n" % _wrap(vowel,i))
            orchlines.append("iRegister init %s\n" % _wrap(voicetype,i))
            orchlines.append("iNewNoteFadeIn init %s\n" % _wrap(fadein,i))
            orchlines.append("iNewNoteFadeOut init %s\n" % _wrap(fadeout,i))
            orchlines.append("iVowelArticulation init %s\n" % _wrap(vowelarticulation,i))
            orchlines.append("iConsArticulation init %s\n" % _wrap(consonantarticulation,i))
            orchlines.append("iFreqPortamento init %s\n" % _wrap(pitchglissando,i))
            orchlines.append("iVowelPortamento init %s\n" % _wrap(vowelglissando,i))
            orchlines.append("iRought init %s\n" % _wrap(roughness,i))
            orchlines.append("iResonance init %s\n" % _wrap(formantresonance,i))
            orchlines.append("iBrillance init %s\n" % _wrap(brilliance,i))
            orchlines.append("iGlotte init %s\n" % _wrap(glotalresonance,i))
            orchlines.append("iVibratoAmplitude	init iCps*%s\n" % _wrap(vibratoamp,i))
            orchlines.append("iVibratoSpeed init %s\n" % _wrap(vibratospeed,i))
            for filename in ['initNoteMidi.txt', 'initVowelMidi.txt', 'initConsonantMidi.txt', 'tiedMidi.txt', 'transitionsMidi.txt', 'processMidi.txt']:
                orchlines.append('#include "' + os.path.join(resources_path, 'voiceSynth', filename) + '"\n')
            orchlines.append("a0%d butterhp aVoice, 250\n" % i)
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('voiceSynth', int(_whichVars(vars) + offset))
    pval = 21
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for filename in ['loadInit.txt', 'initNote.txt', 'initVowel.txt', 'initConsonant.txt', 'tied.txt', 'transitions.txt', 'process.txt']:
            orchlines.append('#include "' + os.path.join(resources_path, 'voiceSynth', filename) + '"\n')
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'consonant', 'vowel', 'voicetype', 'fadein', 'fadeout', 'vowelarticulation', 'consonantarticulation', 'pitchglissando', 'vowelglissando', 'roughness', 'formantresonance', 'brilliance', 'glotalresonance', 'vibratoamp', 'vibratospeed']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        if _wrap(duration,i) < 0 or _wrap(voicenumber,i): line = "i%s " % str(instrument + (_wrap(voicenumber,i)*0.001))
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(consonant,i), _wrap(vowel,i), _wrap(voicetype,i), _wrap(fadein,i), _wrap(fadeout,i), _wrap(vowelarticulation,i), _wrap(consonantarticulation,i), _wrap(pitchglissando,i), _wrap(vowelglissando,i), _wrap(roughness,i), _wrap(formantresonance,i), _wrap(brilliance,i), _wrap(glotalresonance,i), _wrap(vibratoamp,i), _wrap(vibratospeed,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

    voiceSynthesis = False

def train(pitch=250, amplitude=0.7, duration=None, starttime=0, pan=0.5, numharms=40, lowharm=0, damp=.9, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, numharmsVar=None, lowharmVar=None, dampVar=None, out='dac'):
    """Plays a pulse train synthesis sound.

pitch = 250
amplitude = 0.7
duration = None
starttime = 0
numharms = 40
lowharm = 0
damp = .9
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
numharmsVar = None
lowharmVar = None
dampVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = nh = low = dmp = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar, numharmsVar, lowharmVar, dampVar]
    pitch, amplitude, starttime, duration, pan, numharms, lowharm, damp = _convertToList(pitch, amplitude, starttime,
                                                                                    duration, pan, numharms, lowharm, damp)
    envelope, pitchVar, amplitudeVar, panVar, numharmsVar, lowharmVar, dampVar = _convertVarToList(envelope, pitchVar, amplitudeVar,
                                                                                    panVar, numharmsVar, lowharmVar, dampVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(numharms), len(lowharm), len(damp),
              _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(numharmsVar), _len(lowharmVar), _len(dampVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("a0%d gbuzz 32000*%s" % (i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
            orchlines.append(", %s*kpit" % _wrap(pitch,i))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", %s" % _wrap(numharms,i))
            if numharmsVar:
                orchlines.append("*kbus%s" % _wrap(numharmsVar,i))
            orchlines.append(", %s" % _wrap(lowharm,i))
            if lowharmVar:
                orchlines.append("*kbus%s" % _wrap(lowharmVar,i))
            orchlines.append(", %s" % _wrap(damp,i))
            if dampVar:
                orchlines.append("*kbus%s" % _wrap(dampVar,i))
            orchlines.append(", 4\n")
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('train', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if numharmsVar:
            pval, nh = _setxxxVar(pval, 'nh')
        if lowharmVar:
            pval, low = _setxxxVar(pval, 'low')
        if dampVar:
            pval, dmp = _setxxxVar(pval, 'dmp')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)
        orchlines.append("a0 gbuzz 32000*p5%s%s, p4%s, p6%s, p7%s, p8%s, 4\n" % (env, amp, pit, nh, low, dmp))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'numharms', 'lowharm', 'damp']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar') 
    if numharmsVar: paramDict[procNum][str(instrument)].append('numharmsVar')
    if lowharmVar: paramDict[procNum][str(instrument)].append('lowharmVar')
    if dampVar: paramDict[procNum][str(instrument)].append('dampVar')
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(numharms,i), _wrap(lowharm,i), _wrap(damp,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if numharmsVar: line += "%s " % _kbusget(_wrap(numharmsVar,i))
        if lowharmVar: line += "%s " % _kbusget(_wrap(lowharmVar,i))
        if dampVar: line += "%s " % _kbusget(_wrap(dampVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def pulsar(pitch=100, amplitude=0.7, duration=None, starttime=0, tablelen=.5, pan=0.5, phase=0, wavetable='default', 
           envtable='default', pitchVar=None, amplitudeVar=None, panVar=None, tablelenVar=None, out='dac'):
    """Generates a pulsar synthesis sound.

pitch = 100
amplitude = 0.7
duration = None
starttime = 0
tablelen = 0.5
pan = 0.5
phase = 0
wavetable = 'default'
envtable = 'default' # 'default' means no envelope
pitchVar = None
amplitudeVar = None
panVar = None
tablelenVar = None
out = 'dac'

--- PARAMETERS ---

pitch : Frequency in cycles per seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
tablelen : Length, between 0 and 1, of the waveform in fraction of the frequency period. Rest are filled with zeros.
pan : Position value between 0 and 1.
phase : Initial phase of the frequency period.
wavetable : Waveform used to generate the pulsar impulse.
envtable : Envelope applied on the pulsar impulse.
pitchVar : Name of the control bus multiplying pitch value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
tablelenVar : Name of the control bus multiplying tablelen value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    if wavetable == 'default': wavetable = 10
    if envtable == 'default': envtable = 11

    ipanpval = outpval = 0
    pit = amp = panval = frac = ''
    vars = [pitchVar, amplitudeVar, panVar, tablelenVar]
    pitch, amplitude, starttime, duration, pan, tablelen, phase, wavetable, envtable = _convertToList(pitch, amplitude, starttime, duration, pan, tablelen,
                                                                                                      phase, wavetable, envtable)
    pitchVar, amplitudeVar, panVar, tablelenVar = _convertVarToList(pitchVar, amplitudeVar, panVar, tablelenVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(tablelen), len(phase), len(wavetable), len(envtable),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(tablelenVar))

    if not 'pulsar' in UDO:
        UDO.append('pulsar')

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab = _wrap(wavetable,i)[0]
            except:
                tab = _wrap(wavetable,i)
            orchlines.append("a0%d pulsar %s*kpit" % (i, _wrap(pitch,i)))
            if pitchVar:
                orchlines.append("*kbus%s" % _wrap(pitchVar,i))
            orchlines.append(", %s" % _wrap(tablelen,i))
            if tablelenVar:
                orchlines.append("*kbus%s" % _wrap(tablelenVar,i))
            orchlines.append(", %s, %s, %s\n" % (tab, _wrap(envtable,i), _wrap(phase,i)))
            orchlines.append("a0%s = a0%s * 32000 * %s" % (i, i, _wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
            else:
                orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, 1, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('pulsar', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if tablelenVar:
            pval, frac = _setxxxVar(pval, 'frac')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("a0 pulsar p4%s, p6%s, p7, p8, p9\na0 = a0 * 32000 * p5%s\n" % (pit, frac, amp))
        _outPanSig(out, outpval, ipanpval, panval, 1, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'tablelen', 'wavetable', 'envtable', 'phase']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if tablelenVar: paramDict[procNum][str(instrument)].append('tablelenVar')
    for i in range(seq):
        try:
            tab = _wrap(wavetable,i)[0]
        except:
            tab = _wrap(wavetable,i)
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += "%s %s %s %s %s %s %s %s " % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(tablelen,i), tab, _wrap(envtable,i), _wrap(phase,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if tablelenVar: line += "%s " % _kbusget(_wrap(tablelenVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


######################################################
################ Custom instruments ##################
# why not panVar?
def myInstrument(file='', starttime=0, duration=None, pan=0.5, argslist=[], vardict={}, nosound=False, out='dac'):
    """Define a custom csound instrument.
    
file = path_to_text_file
starttime = 0
duration = None
pan = 0.5
argslist = []
vardict = {}
nosound = False
out = 'dac'

argslist are list of pfield values

vardict are dictionary of control bus. Keys in vardict refer to 'k + "key"' variable in the csound instrument. Values are input bus."""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    panval = ''

    file, starttime, duration, pan = _convertToList(file, starttime, duration, pan)

    lenlist = [len(file), len(starttime), len(duration), len(pan)]
        
    for i in range(len(argslist)):
        if type(argslist[i]) != ListType: argslist[i] = [argslist[i]]

    for key in vardict.keys():
        if type(vardict[key]) != ListType: vardict[key] = [vardict[key]]
        
    for i in argslist:
        lenlist.append(len(i))
        
    for key in vardict.keys():
        lenlist.append(len(vardict[key]))

    varkeylist = vardict.keys()
    if len(varkeylist) > 1: sortedVar = sorted(varkeylist)
    else: sortedVar = varkeylist
    
    seq = max(lenlist)

    if out != 'dac':
        out = _zakset(out)   
        
    outstring = ['out ', 'outs', 'outq', 'outo']  
    outnum = [1,2,4,8]
    chn = 1

    for eachfile in file:   
        instrument = _checkInst('myInstrument', 0, True)    
        orchlines.append("instr %d\n" % instrument)
        pval = len(argslist) + 4
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if sortedVar:   
            for key in sortedVar:
                pval = _setVar(pval, key)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument) 

        if os.path.isfile(eachfile):
            eachfile = eachfile
        elif project_paths:
            for path in project_paths:
                if os.path.isfile(os.path.join(path, eachfile)):
                    eachfile = os.path.join(path, eachfile)
                    break
        else:
            raise('File does not exist')
       
        f = open(eachfile, "r")
        for line in f.readlines():
            if not 'instr' in line and not 'out' in line and not 'endin' in line:
                orchlines.append(line)
            if 'out' in line:    
                for outstr in outstring:
                    if outstr in line:
                        chn = outnum[outstring.index(outstr)]
                        linesplit = line.split()
                        for n in range(chn):
                            orchlines.append("a%s = %s\n" % (n, linesplit[n+1].strip(',')))
        if not nosound:
            _outPanSig(out, outpval, ipanpval, panval, chn, _checkChannels())
        else:
            orchlines.append('endin\n\n')

        paramDict[procNum][str(instrument)] = ['starttime', 'duration']
        for k in range(len(argslist)):
            paramDict[procNum][str(instrument)].append('p%s' % str(k+4))
        if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
        if sortedVar:
            for key in sortedVar:
                paramDict[procNum][str(instrument)].append(key)
        for i in range(seq):        
            if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
            else: line = "i%s " % str(instrument)
            line += "%s %s " % (_wrap(starttime,i), _wrap(duration,i))
            for arg in argslist:
                line += "%s " % _wrap(arg,i)
            if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
            if sortedVar:
                for key in sortedVar:
                    line += "%s " % _kbusget(_wrap(vardict[key],i))
            if out != 'dac': line += "%s" % out
            line += "\n"
            _routeScoreline(line)
 
 
######################################################
############## Process on sound table ################
def soundTableRead(table, pitch=1, amplitude=1, starttime=0, duration=None, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Read a sound table once.

table = table_number
pitch = 1
amplitude = 1
starttime = 0
duration = None
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, table = _convertToList(pitch, amplitude, starttime, duration, pan, table)
    envelope, pitchVar, amplitudeVar, panVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar)
    seq = max(len(table), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab = _wrap(table,i)[0]
                tabLen = len(_wrap(table,i))
            except:
                tab = _wrap(table,i)
                tabLen = 1
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = _wrap(table,i)[j]
                orchlines.append("a%s%d loscil3 1, %s*kpit" % (j, i, _wrap(pitch,i)))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", %d, 1\n" % tab)    
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('soundTableRead', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        try:
            tableLen = len(table[0])
        except:
            tableLen = 1
        for j in range(tableLen):
            orchlines.append("a%d loscil3 p5%s%s, p4%s, p6+%d, 1\n" % (j, env, amp, pit, j))
        _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'table']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        try:
            tab = str(table[i%len(table)][0])
        except:
            tab = _wrap(table,i)

        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), tab)
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def looper(table, pitch=1, amplitude=1, starttime=0, looplength=1, duration=None, pan=0.5, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Loops a sound table.

table = table_number
pitch = 1
amplitude = 1
duration = None
starttime = 0
looplength = 1
pan = 0.5
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, table, looplength = _convertToList(pitch, amplitude, starttime, duration, pan, table, looplength)
    envelope, pitchVar, amplitudeVar, panVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar)
    seq = max(len(table), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(looplength), _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab = _wrap(table,i)[0]
                tabLen = len(_wrap(table,i))
            except:
                tab = _wrap(table,i)
                tabLen = 1
            orchlines.append("isamps%d = nsamp(%d)\n" % (i, tab))
            orchlines.append("ifsr%d = ftsr(%d)\n" % (i, tab))
            orchlines.append("if isamps%d != 0 igoto continue%d\n" % (i, i))
            orchlines.append("isamps%d tableng %d\n" % (i, tab))
            orchlines.append("ifsr%d = sr\n" % i)
            orchlines.append("continue%d:\n" % i)
            orchlines.append("ifrac%d = isamps%d/ftlen(%d)\nifreq%d = ifsr%d/ftlen(%d)\n" % (i, i, tab, i, i, tab))
            orchlines.append("aindex%d phasor ifreq%d*(1/ifrac%d)*(1/%s)*%s*kpit" % (i, i, i, _wrap(looplength,i), _wrap(pitch,i)))
            if pitchVar:
                orchlines.append("*kbus%s\n" % _wrap(pitchVar,i))
            else:
                orchlines.append("\n")
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = _wrap(table,i)[j]
                orchlines.append("a%s%d tablei aindex%d*ifrac%d*%s, %d, 1\n" % (j, i, i, i, _wrap(looplength,i), tabInd))
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('looper', int(_whichVars(vars) + offset))
    pval = 8
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("isamps = nsamp(p6)\n")
        orchlines.append("ifsr = ftsr(p6)\n")
        orchlines.append("if isamps != 0 igoto continue\n")
        orchlines.append("isamps tableng p6\n")
        orchlines.append("ifsr = sr\n")
        orchlines.append("continue:\n")
        orchlines.append("ifrac = isamps/ftlen(p6)\nifreq = ifsr/ftlen(p6)\n")
        orchlines.append("aindex phasor ifreq*(1/ifrac)*(1/p7)*p4%s\n" % pit)

        try:
            tableLen = len(table[0])
        except:
            tableLen = 1
        for j in range(tableLen):
            orchlines.append("a%d tablei aindex*ifrac*p7, p6+%d, 1\n" % (j, j))
            orchlines.append("a%d = a%d *p5%s%s\n" % (j, j, env, amp))
        _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'table', 'looplength']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        try:
            tab = str(table[i%len(table)][0])
        except:
            tab = _wrap(table,i)

        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), tab, _wrap(looplength,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def flooper(table, pitch=1, amplitude=1, starttime=0, duration=None, pan=0.5, startpoint=0, loopmode=0, loopstart=0, loopend=1, crossfade=.005, 
            envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, loopstartVar=None, loopendVar=None, crossfadeVar=None, out='dac'):
    """Loops a sound table with variable loop points.

table = table_number
pitch = 1
amplitude = 1
starttime = 0
duration = None
pan = 0.5
startpoint = 0
loopmode = 0 
loopstart = 0
loopend = 1
crossfade = .005
envelope = None
pitchVar = None
amplitudeVar = None
panVar = None
loopstartVar = None
loopendVar = None
crossfadeVar = None
out = 'dac'

* loopmode can be 0 (forward), 1 (backward) or 2 (back-and-forth) 
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = lps = lpe = cro = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar, loopstartVar, loopendVar, crossfadeVar]
    pitch, amplitude, starttime, duration, pan, table, startpoint, loopmode, loopstart, loopend, crossfade = _convertToList(pitch, amplitude, starttime, 
                                                                                            duration, pan, table, startpoint, loopmode, loopstart, loopend, crossfade)
    envelope, pitchVar, amplitudeVar, panVar, loopstartVar, loopendVar, crossfadeVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar, loopstartVar, loopendVar, crossfadeVar)
    seq = max(len(table), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(startpoint), len(loopmode), len(loopstart), len(loopend), len(crossfade),
              _len(loopstartVar), _len(loopendVar), _len(crossfadeVar), _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab = _wrap(table,i)[0]
                tabLen = len(_wrap(table,i))
            except:
                tab = _wrap(table,i)
                tabLen = 1
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = _wrap(table,i)[j]
                orchlines.append("a%s%d flooper2 1, %s*kpit" % (j, i, _wrap(pitch,i)))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", %s" % _wrap(loopstart,i))
                if loopstartVar:
                    orchlines.append("*kbus%s" % _wrap(loopstartVar,i))
                orchlines.append(", %s" % _wrap(loopend,i))
                if loopendVar:
                    orchlines.append("*kbus%s" % _wrap(loopendVar,i))
                orchlines.append(", %s" % _wrap(crossfade,i))
                if crossfadeVar:
                    orchlines.append("*kbus%s" % _wrap(crossfadeVar,i))
                orchlines.append(", %d, %d, %d\n" % (tab, startpoint, loopmode))    
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('flooper', int(_whichVars(vars) + offset))
    pval = 12
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if loopstartVar:
            pval, lps = _setxxxVar(pval, 'lps')
        if loopendVar:
            pval, lpe = _setxxxVar(pval, 'lpe')
        if crossfadeVar:
            pval, cro = _setxxxVar(pval, 'cro')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        try:
            tableLen = len(table[0])
        except:
            tableLen = 1
        for j in range(tableLen):
            orchlines.append("a%d flooper2 p5%s%s, p4%s, p9%s, p10%s, p11%s, p6, p7, p8\n" % (j, env, amp, pit, lps, lpe, cro))
        _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'table', 'startpoint', 'loopmode', 'loopstart', 'loopend', 'crossfade']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if loopstartVar: paramDict[procNum][str(instrument)].append('loopstartVar')
    if loopendVar: paramDict[procNum][str(instrument)].append('loopendVar')
    if crossfadeVar: paramDict[procNum][str(instrument)].append('crossfadeVar')
    for i in range(seq):
        try:
            tab = str(table[i%len(table)][0])
        except:
            tab = _wrap(table,i)

        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), tab, _wrap(startpoint,i), _wrap(loopmode,i), _wrap(loopstart,i), _wrap(loopend,i), _wrap(crossfade,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if loopstartVar: line += "%s " % _kbusget(_wrap(loopstartVar,i))
        if loopendVar: line += "%s " % _kbusget(_wrap(loopendVar,i))
        if crossfadeVar: line += "%s " % _kbusget(_wrap(crossfadeVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def warper(table, pitch=1, amplitude=1, starttime=0, duration=None, pan=0.5, warp=1, windowsize=4410, windrand=882, overlaps=15, envelope=None, pitchVar=None, amplitudeVar=None, panVar=None, warpVar=None, out='dac'):
    """Stretches or pitch shifts a sound table.

table = table_number
pitch = 1
amplitude = 1
duration = None
starttime = 0
pan = 0.5
warp = 1
windowsize = 4410 # samples
windrand = 882 # samples
overlaps = 15
envelope = None
pitchVar = None
amplitudeVar = None
warpVar = None
panVar = None
out = 'dac'

* does not work with table generated with recordBuffer"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    env = pit = amp = panval = wrp = ''
    vars = [envelope, pitchVar, amplitudeVar, panVar, warpVar]
    pitch, amplitude, starttime, duration, pan, table, warp, windowsize, windrand, overlaps = _convertToList(pitch, amplitude, starttime,
                                                                            duration, pan, table, warp, windowsize, windrand, overlaps)
    envelope, pitchVar, amplitudeVar, panVar, warpVar = _convertVarToList(envelope, pitchVar, amplitudeVar, panVar, warpVar)
    seq = max(len(pitch), len(table), len(amplitude), len(starttime), len(duration), len(pan), len(warp), len(windowsize), len(windrand), len(overlaps),
               _len(envelope), _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(warpVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab = table[i%len(table)][0]
                tabLen = len(table[i%len(table)])
            except:
                tab = table[i%len(table)]
                tabLen = 1
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = tab[j]
                orchlines.append("a%s%d, acomp%s%d sndwarp %s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s" % _wrap(amplitudeVar,i))
                orchlines.append(", %s" % str(warp[i%len(warp)]))
                if warpVar:
                    orchlines.append("*kbus%s" % str(warpVar[i%len(warpVar)]))
                orchlines.append(", %s*kpit" % _wrap(pitch,i))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", %d, 0, %s, %s, %s, 5, 0\n" % (tabInd, str(windowsize[i%len(windowsize)]), str(windrand[i%len(windrand)]), str(overlaps[i%len(overlaps)])))
                orchlines.append("a%s%d balance a%s%d, acomp%s%d\n" % (j, i, j, i, j, i))
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return


    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('warper', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if envelope:
            pval, env = _setenvelope(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if warpVar:
            pval, wrp = _setxxxVar(pval, 'wrp')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        try:
            tableLen = len(table[0])
        except:
            tableLen = 1
        for j in range(tableLen):
            orchlines.append("ain%d, acp%d sndwarp p5%s%s, p6%s, p4%s, p7+%d, 0, p8, p9, p10, 5, 0\n" % (j, j, env, amp, wrp, pit, j))
            orchlines.append("a%d balance ain%d, acp%d\n" % (j, j, j))
        _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'warp', 'table', 'windowsize', 'windrand', 'overlaps']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if envelope: paramDict[procNum][str(instrument)].append('envelope')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if warpVar: paramDict[procNum][str(instrument)].append('warpVar')
    for i in range(seq):
        try:
            tab = str(table[i%len(table)][0])
        except:
            tab = _wrap(table,i)
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), str(warp[i%len(warp)]), tab, str(windowsize[i%len(windowsize)]), str(windrand[i%len(windrand)]), str(overlaps[i%len(overlaps)]))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if envelope: line += "%s " % _wrap(envelope,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if warpVar: line += "%s " % str(_kbusget(warpVar[i%len(warpVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def granulator(table, pitch=1, amplitude=1, duration=None, starttime=0, pan=0.5, grainenvelope='default', overlaps=2,
               grainsize=0.1, pointerrate=1, pitchVar=None, amplitudeVar=None, panVar=None, grainsizeVar=None,
               pointerrateVar=None, out='dac'):
    """Granulates a soundfile stored in a table. Gives control on the pointer rate.

table = sound_table
pitch = 1
amplitude = 1
duration = None
starttime = 0
pan = 0.5
grainenvelope = 'default'
overlaps = 2
grainsize = 0.1
pointerrate = 1
pitchVar = None
amplitudeVar = None
panVar = None
grainsizeVar = None
pointerrateVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = siz = pt = ''
    vars = [pitchVar, amplitudeVar, panVar, grainsizeVar, pointerrateVar]
    table, pitch, amplitude, starttime, duration, pan = _convertToList(table, pitch, amplitude, starttime, duration, pan)
    grainenvelope, overlaps, grainsize, pointerrate = _convertToList(grainenvelope, overlaps, grainsize, pointerrate)
    pitchVar, amplitudeVar, panVar, grainsizeVar, pointerrateVar = _convertVarToList(pitchVar, amplitudeVar, panVar, grainsizeVar, pointerrateVar)
    seq = max(len(table), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(overlaps), len(grainsize), len(grainenvelope), len(pointerrate),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(grainsizeVar), _len(pointerrateVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in max(range(seq), len(table)):
            if _wrap(grainenvelope,i) == 'default': wave = 6
            else: wave = _wrap(grainenvelope,i)
            try:
                tab = _wrap(table,i)[0]
                tabLen = len(_wrap(table,i))
            except:
                tab = _wrap(table,i)
                tabLen = 1
            orchlines.append("kgramp%d = %s" % (i,_wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrpitch%d = %s*kpit" % (i,_wrap(pitch,i)))
            if pitchVar:
                orchlines.append("*kbus%s\n" % _wrap(pitchVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrsize%d = %s" % (i,_wrap(grainsize,i)))
            if grainsizeVar:
                orchlines.append("*kbus%s\n" % _wrap(grainsizeVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrpointer%d = %s" % (i,_wrap(pointerrate,i)))
            if pointerrateVar:
                orchlines.append("*kbus%s\n" % _wrap(pointerrateVar,i))
            else:
                orchlines.append("\n")
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = _wrap(table,i)[j]
                orchlines.append("a%s%d syncgrain kgramp%d, %s/kgrsize%d, kgrpitch%d, kgrsize%d, kgrpointer%d, %s, %s, %s\n" % (j, i, i, _wrap(overlaps,i), i, i, i, i, tabInd, wave, _wrap(overlaps,i)))
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    for i in range(seq):
        try:
            tableLen = len(_wrap(table,i))
        except:
            tableLen = 1
        instrument = _checkInst('granulator', int(_whichVars(vars) + offset + tableLen))
        pval = 11
        if not instrument in instrlist:
            orchlines.append("instr %d\n" % instrument)
            if _checkChannels() > 1:
                ipanpval, pval = _setpan(pval)
            if pitchVar:
                pval, pit = _setxxxVar(pval, 'pit')
            if amplitudeVar:
                pval, amp = _setxxxVar(pval, 'amp')
            if panVar:
                pval, panval = _setpanVar(pval)
            if grainsizeVar:
                pval, siz = _setxxxVar(pval, 'siz')
            if pointerrateVar:
                pval, pt = _setxxxVar(pval, 'pt')
            if out != 'dac':
                outpval = pval
            instrlist.append(instrument)

            for j in range(tableLen):
                orchlines.append("a%d syncgrain p5%s, p10/(p6%s), p4%s, p6%s, (1/p10)*p7%s, p8+%d, p9, p10\n" % (j, amp, siz, pit, siz, pt, j))
            _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

        try:
            tab = str(_wrap(table,i)[0])
        except:
            tab = _wrap(table,i)
        if _wrap(grainenvelope,i) == 'default': wave = 6
        else: wave = _wrap(grainenvelope,i)
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(grainsize,i), _wrap(pointerrate,i), tab, wave, _wrap(overlaps,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if grainsizeVar: line += "%s " % _kbusget(_wrap(grainsizeVar,i))
        if pointerrateVar: line += "%s " % _kbusget(_wrap(pointerrateVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'grainsize', 'pointerrate', 'table', 'grainenvelope', 'overlaps']
        if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
        if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if panVar: paramDict[procNum][str(instrument)].append('panVar')
        if grainsizeVar: paramDict[procNum][str(instrument)].append('grainsizeVar')
        if pointerrateVar: paramDict[procNum][str(instrument)].append('pointerrateVar')
        _routeScoreline(line)

def granulator2(table, pitch=1, amplitude=1, duration=None, starttime=0, pan=0.5, grainenvelope='default', overlaps=2,
               grainsize=0.1, pointerpos=0, pitchVar=None, amplitudeVar=None, panVar=None, grainsizeVar=None, randgrainsizeVar=None,
               pointerposVar=None, randpointerposVar=None, out='dac'):
    """Granulates a sound file stored in a table. Gives control on normalized pointer position (0 -> 1).

table = sound_table
pitch = 1
amplitude = 1
duration = None
starttime = 0
pan = 0.5
grainenvelope = 'default'
overlaps = 2
grainsize = 0.1
pointerpos = 0
pitchVar = None
amplitudeVar = None
panVar = None
grainsizeVar = None
randgrainsizeVar = None
pointerposVar = None
randpointerposVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = siz = rsiz = pt = rpt = ''
    vars = [pitchVar, amplitudeVar, panVar, grainsizeVar, randgrainsizeVar, pointerposVar, randpointerposVar]
    table, pitch, amplitude, starttime, duration, pan = _convertToList(table, pitch, amplitude, starttime, duration, pan)
    grainenvelope, overlaps, grainsize, pointerpos = _convertToList(grainenvelope, overlaps, grainsize, pointerpos)
    pitchVar, amplitudeVar, panVar, grainsizeVar, randgrainsizeVar, pointerposVar, randpointerposVar = _convertVarToList(pitchVar, amplitudeVar, panVar, 
                                                                                                grainsizeVar, randgrainsizeVar, pointerposVar, randpointerposVar)
    seq = max(len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(overlaps), len(grainsize), len(grainenvelope), len(pointerpos),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(grainsizeVar), _len(randgrainsizeVar), _len(pointerposVar), _len(randpointerposVar))

    if not 'myGrain' in UDO:
        UDO.append('myGrain')
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in max(range(seq), len(table)):
            if _wrap(grainenvelope,i) == 'default': wave = 6
            else: wave = _wrap(grainenvelope,i)
            try:
                tab = _wrap(table,i)[0]
                tabLen = len(_wrap(table,i))
            except:
                tab = _wrap(table,i)
                tabLen = 1
            orchlines.append("kamp%d = %s" % (i,_wrap(amplitude,i)))
            if amplitudeVar:
                orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrpitch%d = %s" % (i,_wrap(pitch,i)))
            if pitchVar:
                orchlines.append("*kbus%s\n" % _wrap(pitchVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrsize%d = %s" % (i,_wrap(grainsize,i)))
            if grainsizeVar:
                orchlines.append("*kbus%s\n" % _wrap(grainsizeVar,i))
            else:
                orchlines.append("\n")
            orchlines.append("kgrpointer%d = %s" % (i,_wrap(pointerpos,i)))
            if pointerposVar:
                orchlines.append("*kbus%s\n" % _wrap(pointerposVar,i))
            else:
                orchlines.append("\n")
            if randgrainsizeVar:
                orchlines.append("krndsizvar = kbus%s\n" % _wrap(randgrainsizeVar,i))
            else:
                orchlines.append("krndsizeVar = 1\n")    
            if randpointerposVar:
                orchlines.append("krndposvar = kbus%s\n" % _wrap(randpointerposVar,i))
            else:
                orchlines.append("krndposvar = 0\n")                 
                
            orchlines.append("kgrpitch%d = kgrpitch%d / kgrsize%d\n" % (i,i,i))
            for j in range(tabLen):
                if tabLen == 1: tabInd = tab
                else: tabInd = _wrap(table,i)[j]
                orchlines.append("a%s%d = 0\n" % (j, i))
                for k in range(_wrap(overlaps,i)):
                    phase = ((k*1.) / (_wrap(overlaps,i)+1)) * (1 + (random.randint(0, 100)*0.002))
                    orchlines.append("a%s%d%d myGrain kgrpointer%d, kgrsize%d, kgrpitch%d*kpit, krndsizvar, krndposvar, %s, %s, %s\n" % (j, i, k, i, i, i, phase, tabInd, wave))
                    orchlines.append("a%s%d = a%s%d + a%s%d%d\n" % (j, i, j, i, j, i, k))
                orchlines.append("a%s%d = a%s%d * kamp%d\n" % (j, i, j, i, i))    
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    for i in range(seq):
        try:
            tableLen = len(_wrap(table,i))
        except:
            tableLen = 1
        instrument = _checkInst('granulator2', int(_whichVars(vars) + offset + tableLen))
        pval = 10
        if not instrument in instrlist:
            orchlines.append("instr %d\n" % instrument)
            if _checkChannels() > 1:
                ipanpval, pval = _setpan(pval)
            if pitchVar:
                pval, pit = _setxxxVar(pval, 'pit')
            if amplitudeVar:
                pval, amp = _setxxxVar(pval, 'amp')
            if panVar:
                pval, panval = _setpanVar(pval)
            if grainsizeVar:
                pval, siz = _setxxxVar(pval, 'siz')
            if pointerposVar:
                pval, pt = _setxxxVar(pval, 'pt')
            if randgrainsizeVar:
                pval, rsiz = _setxxxVar(pval, 'rsiz')      
            if randpointerposVar:
                pval, rpt = _setxxxVar(pval, 'rpt')      
            if out != 'dac':
                outpval = pval
            instrlist.append(instrument)

            orchlines.append("krndpos random .997, 1.003\n")
            orchlines.append("kpos = abs(p7*krndpos%s)\n" % pt)
            orchlines.append("krnddur random .997, 1.003\n")
            orchlines.append("kdur = p6*krnddur%s\n" % siz)
            orchlines.append("kpitch divz p4%s, p6%s, 0\n" % (pit, siz))
            orchlines.append("krndsizvar = 1%s\n" % rsiz)
            if randpointerposVar:
                orchlines.append("krndposvar = 1%s\n" % rpt)
            else:
                orchlines.append("krndposvar = 0\n")

            if tableLen == 2:
                if not 'myGrain2' in UDO:
                    UDO.append('myGrain2')
                orchlines.append("a0 = 0\n")
                orchlines.append("a1 = 0\n")
                for k in range(_wrap(overlaps,i)):
                    phase = ((k*1.) / (_wrap(overlaps,i)+1)) * (1 + (random.randint(0, 100)*0.004))
                    orchlines.append("a0%d, a1%d myGrain2 kpos, kdur, kpitch, krndsizvar, krndposvar, %s, p8, p8+1, p9\n" % (k, k, phase))
                    orchlines.append("a0 = a0 + a0%d\n" % k)
                    orchlines.append("a1 = a1 + a1%d\n" % k)
                orchlines.append("a0 = a0 * p5%s\n" % amp)    
                orchlines.append("a1 = a1 * p5%s\n" % amp)
            else:    
                for j in range(tableLen):
                    orchlines.append("a%d = 0\n" % j)
                    for k in range(_wrap(overlaps,i)):
                        phase = ((k*1.) / (_wrap(overlaps,i)+1)) * (1 + (random.randint(0, 100)*0.004))
                        orchlines.append("a%d%d myGrain kpos, kdur, kpitch, krndsizvar, krndposvar, %s, p8+%d, p9\n" % (j, k, phase, j))
                        orchlines.append("a%d = a%d + a%d%d\n" % (j, j, j, k))
                    orchlines.append("a%d = a%d * p5%s\n" % (j, j, amp))    
            _outPanSig(out, outpval, ipanpval, panval, tableLen, _checkChannels())

        try:
            tab = str(_wrap(table,i)[0])
        except:
            tab = _wrap(table,i)
        if _wrap(grainenvelope,i) == 'default': wave = 6
        else: wave = _wrap(grainenvelope,i)
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(grainsize,i), _wrap(pointerpos,i), tab, wave)
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if grainsizeVar: line += "%s " % _kbusget(_wrap(grainsizeVar,i))
        if pointerposVar: line += "%s " % _kbusget(_wrap(pointerposVar,i))
        if randgrainsizeVar: line += "%s " % _kbusget(_wrap(randgrainsizeVar,i))
        if randpointerposVar: line += "%s " % _kbusget(_wrap(randpointerposVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'grainsize', 'pointerpos', 'table', 'grainenvelope', 'overlaps']
        if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
        if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if panVar: paramDict[procNum][str(instrument)].append('panVar')
        if grainsizeVar: paramDict[procNum][str(instrument)].append('grainsizeVar')
        if pointerposVar: paramDict[procNum][str(instrument)].append('pointerposVar')
        if randgrainsizeVar: paramDict[procNum][str(instrument)].append('randgrainsizeVar')
        if randpointerposVar: paramDict[procNum][str(instrument)].append('randpointerposVar')
        _routeScoreline(line)

def granulator3(table, outstable, pitch=1, amplitude=1, duration=None, starttime=0, grainenvelope='default', overlaps=2,
               grainsize=0.1, pointerpos=0, pitchVar=None, amplitudeVar=None, grainsizeVar=None,
               pointerposVar=None):
    """Granulates a sound file stored in a table. Gives control on normalized pointer position (0 -> 1). Grains are send directly to outputs given as a Cound table.

table = sound_table
outstable = output_numbers_table # this specify which speaker will receive each overlap stream.
pitch = 1
amplitude = 1
duration = None
starttime = 0
grainenvelope = 'default'
overlaps = 2
grainsize = 0.1
pointerpos = 0
pitchVar = None
amplitudeVar = None
grainsizeVar = None
pointerposVar = None

* setChannels() must be invoke before using this function.
** Can't be used inside midiSynth.
"""
    if not duration: duration = GDUR
    ipanpval = 0
    pit = amp = siz = pt = ''
    vars = [pitchVar, amplitudeVar, grainsizeVar, pointerposVar]
    table, outstable, pitch, amplitude, starttime, duration = _convertToList(table, outstable, pitch, amplitude, starttime, duration)
    grainenvelope, overlaps, grainsize, pointerpos = _convertToList(grainenvelope, overlaps, grainsize, pointerpos)
    pitchVar, amplitudeVar, grainsizeVar, pointerposVar = _convertVarToList(pitchVar, amplitudeVar, grainsizeVar, pointerposVar)
    seq = max(len(pitch), len(outstable), len(amplitude), len(starttime), len(duration), len(overlaps), len(grainsize), len(grainenvelope), len(pointerpos),
              _len(pitchVar), _len(amplitudeVar), _len(grainsizeVar), _len(pointerposVar))

    if not 'myGrain3' in UDO:
        UDO.append('myGrain3')
        
    if midiSynthesizer:
        raise Error("granulator3 can't be used inside midiSynth")  
        return

    offset = int(math.pow(2, len(vars)))
    for i in range(seq):
        try:
            tableLen = len(_wrap(table,i))
        except:
            tableLen = 1
        instrument = _checkInst('granulator3', int(_whichVars(vars) + offset + tableLen))
        pval = 11
        if not instrument in instrlist:
            orchlines.append("instr %d\n" % instrument)
            if pitchVar:
                pval, pit = _setxxxVar(pval, 'pit')
            if amplitudeVar:
                pval, amp = _setxxxVar(pval, 'amp')
            if grainsizeVar:
                pval, siz = _setxxxVar(pval, 'siz')
            if pointerposVar:
                pval, pt = _setxxxVar(pval, 'pt')
            instrlist.append(instrument)

            for j in range(tableLen):
                orchlines.append("a%d = 0\n" % j)
                orchlines.append("kpitch = p4%s / p6\n" % pit)
                for k in range(_wrap(overlaps,i)):
                    phase = ((k*1.) / (_wrap(overlaps,i)+1)) * (1 + (random.randint(0, 100)*0.004))
                    orchlines.append("a%d%d myGrain3 p5%s, p7%s, p6%s, kpitch, %s, p8+%d, p9\n" % (j, k, amp, pt, siz, phase, j))
                    orchlines.append("koutpos table %d, p10\n" % k)
                    orchlines.append("if round(koutpos) == 0 then\n")
                    orchlines.append("gaout0 = a%d%d + gaout0\n" % (j, k))
                    for l in range(_checkChannels()-1):
                        orchlines.append("elseif round(koutpos) == %d then\n" % (l+1))
                        orchlines.append("gaout%d = a%d%d + gaout%d\n" % ((l+1), j, k, (l+1)))
                    orchlines.append("endif\n")
            orchlines.append("endin\n")        

        try:
            tab = str(_wrap(table,i)[0])
        except:
            tab = _wrap(table,i)
        if _wrap(grainenvelope,i) == 'default': wave = 6
        else: wave = _wrap(grainenvelope,i)
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(grainsize,i), _wrap(pointerpos,i), tab, wave, _wrap(outstable,i))
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if grainsizeVar: line += "%s " % _kbusget(_wrap(grainsizeVar,i))
        if pointerposVar: line += "%s " % _kbusget(_wrap(pointerposVar,i))
        line += "\n"
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'grainsize', 'pointerpos', 'table', 'grainenvelope', 'outstable']
        if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if grainsizeVar: paramDict[procNum][str(instrument)].append('grainsizeVar')
        if pointerposVar: paramDict[procNum][str(instrument)].append('pointerposVar')
        _routeScoreline(line)

def tablesMod(table1, table2, index1=1, index2=1, portamento=.01, amplitude=1, starttime=0, duration=None, pan=0.5, index1Var=None, index2Var=None, portamentoVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Ring modulates two tables with index position for each table.

table1 = table_number
table2 = table_number
index1 = 1
index2 = 1
portamento = 0.01
amplitude = 1
starttime = 0
duration = None
pan = 0.5
index1Var = None
index2Var = None
portamentoVar = None
amplitudeVar = None
panVar = None
out = 'dac'
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    ind1 = ind2 = amp = por = panval = ''
    vars = [index1Var, index2Var, portamentoVar, amplitudeVar, panVar]
    index1, index2, portamento, amplitude, starttime, duration, pan, table1, table2 = _convertToList(index1, index2, portamento, amplitude, 
                                                                                                     starttime, duration, pan, table1, table2)
    index1Var, index2Var, portamentoVar, amplitudeVar, panVar = _convertVarToList(index1Var, index2Var, portamentoVar, amplitudeVar, panVar)
    seq = max(len(table1), len(table2), len(index1), len(index2), len(portamento), len(amplitude), len(starttime), len(duration), len(pan), _len(index1Var), 
              _len(index2Var), _len(portamentoVar), _len(amplitudeVar), _len(panVar))

    if not 'tabsMod' in UDO:
        UDO.append('tabsMod')

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            try:
                tab1 = _wrap(table1,i)[0]
                tabLen1 = len(_wrap(table1,i))
            except:
                tab1 = _wrap(table1,i)
                tabLen1 = 1
            try:
                tab2 = _wrap(table2,i)[0]
                tabLen2 = len(_wrap(table2,i))
            except:
                tab2 = _wrap(table2,i)
                tabLen2 = 1
            for j in range(min(tabLen1,tabLen2)):
                if tabLen1 == 1: tabInd1 = tab1
                else: tabInd1 = _wrap(table1,i)[j]
                if tabLen2 == 1: tabInd2 = tab2
                else: tabInd2 = _wrap(table2,i)[j]
                orchlines.append("a%s%d tabsMod %s" % (j, i, _wrap(index1,i)))
                if index1Var:
                    orchlines.append("*kbus%s" % _wrap(index1Var,i))
                orchlines.append(", %s" % _wrap(index2,i))
                if index2Var:
                    orchlines.append("*kbus%s" % _wrap(index2Var,i))
                orchlines.append(", %s" % _wrap(portamento,i))
                if portamentoVar:
                    orchlines.append("*kbus%s" % _wrap(portamentoVar,i))
                orchlines.append(", %d, %d\n" % (tab1, tab2))
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, tabLen, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('tablesMod', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if index1Var:
            pval, ind1 = _setxxxVar(pval, 'ind1')
        if index2Var:
            pval, ind2 = _setxxxVar(pval, 'ind2')
        if portamentoVar:
            pval, por = _setxxxVar(pval, 'por')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        try:
            tableLen1 = len(table1[0])
        except:
            tableLen1 = 1
        try:
            tableLen2 = len(table2[0])
        except:
            tableLen2 = 1
        for j in range(min(tableLen1, tableLen2)):
            orchlines.append("a%d tabsMod p4%s, p6%s, p9%s, p7, p8\n" % (j, ind1, ind2, por))
            orchlines.append("a%d = a%d * p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, min(tableLen1, tableLen2), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'index1', 'amplitude', 'index2', 'table1', 'table2', 'portamento']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if index1Var: paramDict[procNum][str(instrument)].append('index1Var')
    if index2Var: paramDict[procNum][str(instrument)].append('index2Var')
    if portamentoVar: paramDict[procNum][str(instrument)].append('portamentoVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        try:
            tab1 = str(table1[i%len(table1)][0])
        except:
            tab1 = _wrap(table1,i)
        try:
            tab2 = str(table2[i%len(table2)][0])
        except:
            tab2 = _wrap(table2,i)

        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(index1,i), _wrap(amplitude,i), _wrap(index2,i), tab1, tab2, _wrap(portamento,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if index1Var: line += "%s " % _kbusget(_wrap(index1Var,i))
        if index2Var: line += "%s " % _kbusget(_wrap(index2Var,i))
        if portamentoVar: line += "%s " % _kbusget(_wrap(portamentoVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


######################################################
################ Process on sampling #################
def recordAndLoop(input, trigbus, pitch=1, amplitude=1, starttime=0, duration=None, pan=0.5, nchannels=1, loopduration=1, crossfade=0.05, 
                  pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Records audio input and plays it back in a loop.

input = audio_input
trigbus = trigger_bus
pitch = 1
amplitude = 1
duration = None
starttime = 0
pan = 0.5
nchannels = 1
loopduration = 1
crossfade = 0.05
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = ''
    vars = [pitchVar, amplitudeVar, panVar]
    input, trigbus, pitch, amplitude, starttime, duration, pan, nchannels, loopduration, crossfade = _convertToList(input, trigbus, pitch, amplitude, starttime, 
                                                                                                                    duration, pan, nchannels, loopduration, crossfade)
    pitchVar, amplitudeVar, panVar = _convertVarToList(pitchVar, amplitudeVar, panVar)
    seq = max(len(input), len(trigbus), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(nchannels), len(loopduration), 
              len(crossfade), _len(pitchVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            length = _wrap(nchannels,i)
            orchlines.append("kswitch%d init -1\n" % i)
            orchlines.append("kon%d init 0\n" % i)
            orchlines.append('kswitch%d = kbus%s\n' % (i, _wrap(trigbus,i)))
            orchlines.append("kswichanged%d changed kswitch%d\n" % (i, i))
            orchlines.append("if kswichanged%d == 1 && kswitch%d > 0 then\n" % (i, i))
            orchlines.append("if kon%d == 0 then\n" % i)
            orchlines.append("kon%d = 1\n" % i)
            orchlines.append("else\n")
            orchlines.append("kon%d = 0\n" % i)
            orchlines.append("kswitch%d = -1\n" % i)
            orchlines.append("endif\nendif\n")
            for j in range(length):
                orchlines.append("ain%s%d = abus%s%s\n" % (j, i, j, _wrap(input,i)))
                orchlines.append("a%s%d, krec sndloop ain%s%d, %s" % (j, i, j, i, _wrap(pitch,i)))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", kon%d, %s, %s\n" % (i, _wrap(loopduration,i), _wrap(crossfade,i)))  
                orchlines.append("if kon%d == 1 && krec == 0 then\n" % i)
                orchlines.append("a%s%d = a%s%d*%s" % (j, i, j, i, _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("else\n")
                orchlines.append("a%s%d = 0\n" % (j, i))
                orchlines.append("endif\n")
            _outPanMidiSig(i, out, pan, panVar, length, _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    if out != 'dac':
        out = _zakset(out)
    for i in range(seq):
        length = _wrap(nchannels,i)
        instrument = _checkInst('recordAndLoop', 0, True)
        pval = 10    
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("ktrig init -1\n")  
        orchlines.append("kon init 0\n")
        orchlines.append('Strig%dkbus ' % instrument)
        orchlines.append('sprintf "kbus%d"')
        orchlines.append(", p9\n")
        orchlines.append("ktrig chnget Strig%dkbus\n" % instrument)
        
        orchlines.append("kswichanged changed ktrig\n")
        orchlines.append("if kswichanged == 1 && ktrig > 0 then\n")
        orchlines.append("if kon == 0 then\n")
        orchlines.append("kon = 1\n")
        orchlines.append("else\n")
        orchlines.append("kon = 0\n")
        orchlines.append("ktrig = -1\n")
        orchlines.append("endif\nendif\n")
        
        for j in range(length):
            voice = length - (j + 1)
            orchlines.append("ain%d zar p8-%d\n" % (j, voice))
            orchlines.append("a%d, krec sndloop ain%d, p4%s, kon, p6, p7\n" % (j, j, pit))
            orchlines.append("if kon == 1 && krec == 0 then\n")
            orchlines.append("a%d = a%d *p5%s\n" % (j, j, amp))
            orchlines.append("else\n")
            orchlines.append("a%d = 0\n" % j)
            orchlines.append("endif\n")
        _outPanSig(out, outpval, ipanpval, panval, length, _checkChannels())
    
        paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'loopduration', 'crossfade', 'input', 'trigbus']
        if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
        if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
        if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
        if panVar: paramDict[procNum][str(instrument)].append('panVar')

        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(loopduration,i), _wrap(crossfade,i), ainput, _kbusget(_wrap(trigbus,i)))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


######################### Effects instruments ############################
###############################################
############# Effects instruments #############
def ringMod(in1, in2, amplitude=1, duration=None, starttime=0, pan=0.5, amplitudeVar=None, panVar=None, out='dac'):
    """Perform ring modulation on the audio signal.

in1 = first_input
in2 = second_input
amplitude = 1
duration = None
starttime = 0
pan = 0.5
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, in1, in2 = _convertToList(amplitude, starttime, duration, pan, in1, in2)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(in1), len(in2), len(amplitude), len(starttime), len(duration), len(pan), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d = abus%s%s*(abus%s%s/32767)*%s" % (j, i, j, str(in1[i%len(in1)]), j, str(in2[i%len(in2)]), _wrap(amplitude,i)))
                if amplitudeVar:
                    orchlines.append("*kbus%s\n" % _wrap(amplitudeVar,i))
                else:
                    orchlines.append("\n")
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('ringMod', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            num = j
            num2 = num + _checkChannels()
            voice = _checkChannels() - (j + 1)
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
            orchlines.append("ain%d zar p6-%d\n" % (num2, voice))
            orchlines.append("a%d = ain%d*(ain%d/32767)*p5%s\n" % (num, num, num2, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'in1', 'amplitude', 'in2']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(in1[i%len(in1)])
        ainput2 = _zakget(in2[i%len(in2)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), str(ainput2))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
    
def resonator(input, pitch=100, amplitude=1, duration=None, starttime=0, cutoff=6000, feedback=0.99, pan=0.5, pitchVar=None, cutoffVar=None, feedbackVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Audio signal is passed through a resonator.

input = input_sound
pitch = 100
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
feedback = 0.99 # 0 -> 1
pan = 0.5
pitchVar = None
cutoffVar = None
feedbackVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
pitch : Frequency (i.e. the inverse of delay time), in Hertz, of the resonator.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Frequency, in Hertz, of a lowpass filter inside the loop.
feedback : Amount of signal reinjected in the loop (between -1 and 1).
pan : Position value between 0 and 1.
pitchVar : Name of the control bus multiplying pitch value.
cutoffVar : Name of the control bus multiplying cutoff value.
feedbackVar : Name of the control bus multiplying feedback value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = cut = feed = amp = panval = ''
    vars = [pitchVar, cutoffVar, feedbackVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, input, cutoff, feedback = _convertToList(pitch, amplitude, starttime, duration,
                                                                                         pan, input, cutoff, feedback)
    pitchVar, amplitudeVar, panVar, cutoffVar, feedbackVar = _convertVarToList(pitchVar, amplitudeVar, panVar, cutoffVar, feedbackVar)
    seq = max(len(input), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), len(feedback),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(cutoffVar), _len(feedbackVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d wguide1 abus%s%s, %s*kpit" % (j, i, j, _wrap(input,i), _wrap(pitch,i)))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", %s" % _wrap(cutoff,i))
                if cutoffVar:
                    orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                orchlines.append(", %s" % str(feedback[i%len(feedback)]))
                if feedbackVar:
                    orchlines.append("*kbus%s\n" % str(feedbackVar[i%len(feedbackVar)]))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('resonator', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\na%d wguide1 ain%d, p4%s, p6%s, p7%s\n" % (j, voice, j, j, pit, cut, feed))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'cutoff', 'feedback', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(cutoff,i), str(feedback[i%len(feedback)]), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if feedbackVar: line += "%s " % str(_kbusget(feedbackVar[i%len(feedbackVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def distortion(input, amplitude=1, duration=None, starttime=0, drive=.75, cutoff=6000, pan=0.5, driveVar=None, cutoffVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Apply distortion to the audio signal.

input = input_sound
amplitude = 1
duration = None
starttime = 0
drive = 0.75 # 0 -> 1
cutoff = 6000
pan = 0.5
driveVar = None
cutoffVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
drive : Amount of distortion (usually between 0 and 1).
cutoff : Cutoff frequency of the lowpass filter applied on distortion output. 
pan : Position value between 0 and 1.
driveVar : Name of the control bus multiplying drive value.
cutoffVar : Name of the control bus multiplying cutoff value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    drv = cut = amp = panval = ''
    vars = [driveVar, cutoffVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, drive, cutoff = _convertToList(amplitude, starttime, duration, pan, input, drive, cutoff)
    amplitudeVar, panVar, driveVar, cutoffVar = _convertVarToList(amplitudeVar, panVar, driveVar, cutoffVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(drive), len(cutoff), _len(driveVar), 
               _len(cutoffVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            if driveVar:
                orchlines.append("kdrive = .4-(%s*.3999*kbus%s)\n" % (_wrap(drive,i), _wrap(driveVar,i)))
            else:    
                orchlines.append("kdrive = .4-(%s*.3999)\n" % _wrap(drive,i))
            orchlines.append("adrive upsamp kdrive\n")
            orchlines.append("kadjustAmp pow (kdrive+.6), 1.3\n")
            for j in range(_checkChannels()):
                orchlines.append("a%s%d taninv2 abus%s%s/32768, adrive\n" % (j, i, j, _wrap(input,i)))
                orchlines.append("a%s%d butterlp a%s%d, %s" % (j, i, j, i, _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("a%s%d butterlp a%s%d*32000*kadjustAmp, %s" % (j, i, j, i, _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('distortion', int(_whichVars(vars) + offset))
    pval = 8
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if driveVar:
            pval, drv = _setxxxVar(pval, 'drv')
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        if driveVar:
            orchlines.append("kdrive = .4-(p7*.3999%s)\n" % drv)
        else:    
            orchlines.append("kdrive = .4-(p7*.3999)\n")
        orchlines.append("adrive upsamp kdrive\n")
        orchlines.append("kadjustAmp pow (kdrive+.6), 1.3\n")
        
        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p6-%d\n" % (j, voice))
            orchlines.append("a%d taninv2 ain%d/32768, adrive\n" % (j, j))
            orchlines.append("a%d butterlp a%d, p4%s\n" % (j, j, cut))
            orchlines.append("a%d butterlp a%d*32000*kadjustAmp, p4%s\n" % (j, j, cut))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'amplitude', 'input', 'drive']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if driveVar: paramDict[procNum][str(instrument)].append('driveVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), _wrap(amplitude,i), str(ainput), _wrap(drive,1))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if driveVar: line += "%s " % _kbusget(_wrap(driveVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
 
def harmonizer(input, transpo=7, amplitude=1, duration=None, starttime=0, winsize=64, feedback=0, mix=0.5, pan=0.5, transpoVar=None, winsizeVar=None, feedbackVar=None, mixVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Generates harmonizing voices based on the audio signal.

input = input_sound
transpo = 7 # semitones
amplitude = 1
duration = None
starttime = 0
winsize = 64 # ms
feedback = 0 # 0 -> 1
mix = 0.5
pan = 0.5
transpoVar = None
winsizeVar = None
feedbackVar = None
mixVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
transpo : Amount of transposition in semitones.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
winsize : Length of window, in milliseconds.
feedback : Amount of signal reinjected in the loop (between -1 and 1).
mix : Amplitude of transposed sound vs input sound at the output.
pan : Position value between 0 and 1.
transpoVar : Name of the control bus multiplying transpo value.
winsizeVar : Name of the control bus multiplying winsize value.
feedbackVar : Name of the control bus multiplying feedback value.
mixVar : Name of the control bus multiplying mix value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    trans = dly = feed = mx = amp = panval = ''
    vars = [transpoVar, winsizeVar, feedbackVar, mixVar, amplitudeVar, panVar]
    transpo, amplitude, starttime, duration, pan, input, winsize, feedback, mix = _convertToList(transpo, amplitude, starttime, duration,
                                                                                         pan, input, winsize, feedback, mix)
    transpoVar, amplitudeVar, panVar, winsizeVar, feedbackVar, mixVar = _convertVarToList(transpoVar, amplitudeVar, panVar, winsizeVar, feedbackVar, mixVar)
    seq = max(len(input), len(transpo), len(amplitude), len(starttime), len(duration), len(pan), len(winsize), len(feedback), len(mix),
              _len(transpoVar), _len(amplitudeVar), _len(panVar), _len(winsizeVar), _len(feedbackVar), _len(mixVar))

    if not 'harmonizer' in UDO:
        UDO.append('harmonizer')
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d harmonizer abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(winsize,i)))
                if winsizeVar:
                    orchlines.append("*kbus%s" % _wrap(winsizeVar,i))
                orchlines.append(", %s" % _wrap(feedback,i))
                if feedbackVar:
                    orchlines.append("*kbus%s" % _wrap(feedbackVar,i))
                orchlines.append(", %s" % _wrap(transpo,i))
                if transpoVar:
                    orchlines.append("*kbus%s\n" % _wrap(transpoVar,i))
                else:
                    orchlines.append("\n")
                if not mixVar:
                    orchlines.append("a%s%d = (a%s%d * sqrt(%s)) + (abus%s%s * sqrt(1 - %s))\n" % (j, i, j, i, _wrap(mix,i), j, _wrap(input,i), _wrap(mix,i))) 
                else:
                    orchlines.append("a%s%d = (a%s%d * sqrt(%s * kbus%s)) + (abus%s%s * sqrt(1 - (%s * kbus%s)))\n" % (j, i, j, i, _wrap(mix,i), _wrap(mixVar,i), j, _wrap(input,i), _wrap(mix,i), _wrap(mixVar,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('harmonizer', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if transpoVar:
            pval, trans = _setxxxVar(pval, 'trans')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if winsizeVar:
            pval, dly = _setxxxVar(pval, 'dly')
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if mixVar:
            pval, mx = _setxxxVar(pval, 'mx')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\na%d harmonizer ain%d, p6%s, p7%s, p4%s\n" % (j, voice, j, j, dly, feed, trans))
            orchlines.append("a%d = (a%d * sqrt(p9%s)) + (ain%d * sqrt(1 - (p9%s)))\n" % (j, j, mx, j, mx))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'transpo', 'amplitude', 'winsize', 'feedback', 'input', 'mix']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if transpoVar: paramDict[procNum][str(instrument)].append('transpoVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if winsizeVar: paramDict[procNum][str(instrument)].append('winsizeVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    if mixVar: paramDict[procNum][str(instrument)].append('mixVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(transpo,i), _wrap(amplitude,i), _wrap(winsize,i), _wrap(feedback,i), str(ainput), _wrap(mix,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if transpoVar: line += "%s " % _kbusget(_wrap(transpoVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if winsizeVar: line += "%s " % _kbusget(_wrap(winsizeVar,i))
        if feedbackVar: line += "%s " % _kbusget(_wrap(feedbackVar,i))
        if mixVar: line += "%s " % _kbusget(_wrap(mixVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def compressor(input, threshold=-30, amplitude=1, duration=None, starttime=0, lowfactor=1, highfactor=0.5, risetime=0.1, falltime=0.1, pan=0.5, thresholdVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Compress or expand an audio signal.

input = input_sound
threshold = -30 # -90 -> 0 dB
amplitude = 1
duration = None
starttime = 0
lowfactor = 1
highfactor = 0.5
risetime = 0.1
falltime = 0.1
pan = 0.5
thresholdVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    thr = amp = panval = ''
    vars = [thresholdVar, amplitudeVar, panVar]
    threshold, amplitude, starttime, duration, pan, input, lowfactor, highfactor, risetime, falltime = _convertToList(threshold, amplitude, starttime, duration,
                                                                                         pan, input, lowfactor, highfactor, risetime, falltime)
    thresholdVar, amplitudeVar, panVar = _convertVarToList(thresholdVar, amplitudeVar, panVar)
    seq = max(len(input), len(threshold), len(amplitude), len(starttime), len(duration), len(pan), len(lowfactor), len(highfactor), len(risetime), len(falltime),
              _len(thresholdVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d dam abus%s%s, ampdb(90+%s)" % (j, i, j, _wrap(input,i), _wrap(threshold,i)))
                if thresholdVar:
                    orchlines.append("*kbus%s" % _wrap(thresholdVar,i))
                orchlines.append(", %s, %s, %s, %s\n" % (_wrap(highfactor,i), _wrap(lowfactor,i), _wrap(risetime,i), _wrap(hightime,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('compressor', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if thresholdVar:
            pval, thr = _setxxxVar(pval, 'thr')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\na%d dam ain%d, ampdb(90+p4)%s, p7, p6, p9, p10\n" % (j, voice, j, j, thr))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'threshold', 'amplitude', 'lowfactor', 'highfactor', 'input', 'risetime', 'falltime']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if thresholdVar: paramDict[procNum][str(instrument)].append('thresholdVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(threshold,i), _wrap(amplitude,i), _wrap(lowfactor,i), _wrap(highfactor,i), str(ainput), _wrap(risetime,i), _wrap(falltime,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if thresholdVar: line += "%s " % _kbusget(_wrap(thresholdVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def didjeridu(input, pitch=75, amplitude=1, duration=None, starttime=0, drone=1, length=1.5, pressure=0.9, formant=500, resonances=20, pan=0.5, pitchVar=None, droneVar=None, lengthVar=None, pressureVar=None, formantVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Emulate a didjeridu (lips vibration + truncated cone). Input audio signal is modulated by lip vibrations before passing into a bank of resonators.

input = input_sound
pitch = 75
amplitude = 1
duration = None
starttime = 0
pan = 0.5
drone = 1 # switch to turn drone on and off
length = 1.5 # meters
pressure = .9 # 0 -> 1
formant = 500 # mouth resonance frequency
resonances = 20 # how many resonances in the didjeridu (can not be a list)
pitchVar = None
droneVar = None
lengthVar = None
pressureVar = None
formantVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = dro = lth = pres = form = amp = panval = ''
    vars = [pitchVar, droneVar, lengthVar, pressureVar, formantVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, input, drone, length, pressure, formant, resonances = _convertToList(pitch, amplitude, starttime, duration,
                                                                                         pan, input, drone, length, pressure, formant, resonances)
    pitchVar, amplitudeVar, panVar, droneVar, lengthVar, pressureVar, formantVar = _convertVarToList(pitchVar, amplitudeVar, panVar, droneVar, lengthVar,
                                                                                                     pressureVar, formantVar)
    seq = max(len(input), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(drone), len(length), len(pressure), len(formant),
              len(resonances), _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(droneVar), _len(lengthVar), _len(pressureVar), _len(formantVar))

    if not 'didjeres' in UDO:
        UDO.append('didjeres')
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            if not pitchVar:
                orchlines.append("kfreq = %s\n" % _wrap(pitch,i))
            else:
                orchlines.append("kfreq = %s*kbus%s\n" % (_wrap(pitch,i), _wrap(pitchVar,i)))
            if not droneVar:
                orchlines.append("kdrone = %s\n" % _wrap(drone,i))
            else:
                orchlines.append("kdrone = %s*kbus%s\n" % (_wrap(drone,i), _wrap(droneVar,i)))
            if not lengthVar:
                orchlines.append("klength = %s\n" % _wrap(length,i))
            else:
                orchlines.append("klength = %s*kbus%s\n" % (_wrap(length,i), _wrap(lengthVar,i)))
            if not pressureVar:
                orchlines.append("kpressure = %s\n" % _wrap(pressure,i))
            else:
                orchlines.append("kpressure = %s*kbus%s\n" % (_wrap(pressure,i), _wrap(pressureVar,i)))
            if not formantVar:
                orchlines.append("kformant = %s\n" % _wrap(formant,i))
            else:
                orchlines.append("kformant = %s*kbus%s\n" % (_wrap(formant,i), _wrap(formantVar,i)))
                                
            orchlines.append("klowpress limit kpressure, 0, .5\n")
            orchlines.append("klowpress = klowpress * 0.1 + 0.95\n")
            orchlines.append("kpress = kpressure * 0.2 + 0.8\n")
            orchlines.append("kfreqrand jitter2 1, .003, 16, .005, 4.65, .01, .421\n")
            orchlines.append("asine oscili 1, kfreq*(1+kfreqrand)*klowpress, 1\n")
            orchlines.append("kpressrand jitter2 1, .002, 15, .005, 2.76, .008, .12\n")
            orchlines.append("kpress limit kpress*(1+kpressrand), 0, 1\n")
            orchlines.append("asine = asine * 0.5 + 0.5\n")
            orchlines.append("kdrive = .4-(kpress*.3999)\n")
            orchlines.append("adrive upsamp kdrive\n")
            orchlines.append("aexcite taninv2 asine, adrive\n")
            orchlines.append("aexcite = aexcite * 20000 * kpress\n")
            orchlines.append("ashelf rbjeq aexcite, 430, 1+kpressure, 0, .75, 10\n")
            orchlines.append("apeak rbjeq ashelf, kformant, 2, 1.5, 1, 8\n")
            orchlines.append("klength limit klength, 0.1, 10000\n")
            orchlines.append("kd2 = 0.02 + (9.869585 * 0.02 / 16) * (((((8. * kfreq * klength) / 340.) - 1)^2) - 1)\n")
            
            for j in range(_checkChannels()):
                orchlines.append("if kpressure == 0 then\n")
                orchlines.append("aindid%s%d = abus%s%s\n" % (j, i, j, _wrap(input,i)))
                orchlines.append("else\n")
                orchlines.append("aindid%s%d = apeak * (abus%s%s / 32768) + (apeak * 0.2 * kdrone)\n" % (j, i, j, _wrap(input,i)))
                orchlines.append("endif\n")

                for k in range(_wrap(resonances,i)):
                    num = k+1
                    orchlines.append("a%d%s%d didjeres aindid%s%d, klength, kd2, %s, %d\n" % (num, j, i, j, i, _wrap(resonances,i), num))
                orchlines.append("a%s%d = a1%s%d" % (j, i, j, i))   
                for k in range(_wrap(resonances,i)-1):
                    num = k+2
                    orchlines.append("+a%d%s%d" % (num, j, i))
                orchlines.append("\n")    
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('didjeridu', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if droneVar:
            pval, dro = _setxxxVar(pval, 'dro')
        if lengthVar:
            pval, lth = _setxxxVar(pval, 'lth')
        if pressureVar:
            pval, pres = _setxxxVar(pval, 'pres')
        if formantVar:
            pval, form = _setxxxVar(pval, 'form')            
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("kfreq = p4%s\n" % pit)
        orchlines.append("kdrone = p6%s\n" % dro)
        orchlines.append("klength = p7%s\n" % lth)
        orchlines.append("kpressure = p9%s\n" % pres)
        orchlines.append("kformant = p10%s\n" % form)

        orchlines.append("klowpress limit kpressure, 0, .5\n")
        orchlines.append("klowpress = klowpress * 0.1 + 0.95\n")
        orchlines.append("kpress = kpressure * 0.2 + 0.8\n")
        orchlines.append("kfreqrand jitter2 1, .003, 16, .005, 4.65, .01, .421\n")
        orchlines.append("asine oscili 1, kfreq*(1+kfreqrand)*klowpress, 1\n")
        orchlines.append("kpressrand jitter2 1, .002, 15, .005, 2.76, .008, .12\n")
        orchlines.append("kpress limit kpress*(1+kpressrand), 0, 1\n")
        orchlines.append("asine = asine * 0.5 + 0.5\n")
        orchlines.append("kdrive = .4-(kpress*.3999)\n")
        orchlines.append("adrive upsamp kdrive\n")
        orchlines.append("aexcite taninv2 asine, adrive\n")
        orchlines.append("aexcite = aexcite * 20000 * kpress\n")
        orchlines.append("ashelf rbjeq aexcite, 430, 1+kpressure, 0, .75, 10\n")
        orchlines.append("apeak rbjeq ashelf, kformant, 2, 1.5, 1, 8\n")
        orchlines.append("klength limit klength, 0.1, 10000\n")
        orchlines.append("kd2 = 0.02 + (9.869585 * 0.02 / 16) * (((((8. * kfreq * klength) / 340.) - 1)^2) - 1)\n")                
                
        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\n" % (j, voice))
            orchlines.append("if kpressure == 0 then\n")
            orchlines.append("aindid%d = ain%d\n" % (j, j))
            orchlines.append("else\n")
            orchlines.append("aindid%d = apeak * (ain%d / 32768) + (apeak * 0.2 * kdrone)\n" % (j, j))
            orchlines.append("endif\n")
            for k in range(resonances[0]):
                subnum = k+1
                orchlines.append("adid%d didjeres aindid%d, klength, kd2, %s, %d\n" % (subnum, j, resonances[0], subnum))
            orchlines.append("a%d = adid1" % j)   
            for k in range(resonances[0]-1):
                subnum = k+2
                orchlines.append("+adid%d" % (subnum))
            orchlines.append("\n")              
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'drone', 'length', 'input', 'pressure', 'formant']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if droneVar: paramDict[procNum][str(instrument)].append('droneVar')
    if lengthVar: paramDict[procNum][str(instrument)].append('lengthVar')
    if pressureVar: paramDict[procNum][str(instrument)].append('pressureVar')
    if formantVar: paramDict[procNum][str(instrument)].append('formantVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(drone,i), _wrap(length,i), str(ainput), _wrap(pressure,i), _wrap(formant,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if droneVar: line += "%s " % _kbusget(_wrap(droneVar,i))
        if lengthVar: line += "%s " % _kbusget(_wrap(lengthVar,i))
        if pressureVar: line += "%s " % _kbusget(_wrap(pressureVar,i))
        if formantVar: line += "%s " % _kbusget(_wrap(formantVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def delay(input, amplitude=1, duration=None, starttime=0, delaytime=1, pan=0.5, amplitudeVar=None, panVar=None, out='dac'):
    """Delays an input signal by some time interval.

input = input_sound
amplitude = 1
duration = None
starttime = 0
delaytime = 1 # seconds
pan = 0.5
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
delaytime : Requested delay time in seconds. 
pan : Position value between 0 and 1.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, delaytime = _convertToList(amplitude, starttime, duration, pan, input, delaytime)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(delaytime), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d delay abus%s%s, %s\n" % (j, i, j, _wrap(input,i), _wrap(delaytime,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('delay', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p6-%d\na%d delay ain%d, p4\n" % (j, voice, j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'delaytime', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(delaytime,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fold(input, amplitude=1, duration=None, starttime=0, amount=0, pan=0.5, amountVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Adds artificial foldover to an audio signal.

input = input_sound
amplitude = 1
duration = None
starttime = 0
amount = 0
pan = 0.5
amountVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amo = amp = panval = ''
    vars = [amountVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, amount = _convertToList(amplitude, starttime, duration, pan, input, amount)
    amplitudeVar, panVar, amountVar = _convertVarToList(amplitudeVar, panVar, amountVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(amount), _len(amountVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d fold abus%s%s, 1+%s" % (j, i, j, _wrap(input,i), _wrap(amount,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s\n" % _wrap(amountVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fold', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if amountVar:
            pval, amo = _setxxxVar(pval, 'amo')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p6-%d\na%d fold ain%d, 1+p4%s\n" % (j, voice, j, j, amo))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amount', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if amountVar: paramDict[procNum][str(instrument)].append('amountVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amount,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if amountVar: line += "%s " % _kbusget(_wrap(amountVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def vdelay(input, delay=1, amplitude=1, duration=None, starttime=0, feedback=0.5, pan=0.5, delayVar=None, feedbackVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Audio signal is passed through an interpolating variable time delay with feedback.

input = input_sound
delay = 1
amplitude = 1
duration = None
starttime = 0
feedback = 0.5 # 0 -> 1
pan = 0.5
delayVar = None
feedbackVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
delay : Delay in seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
feedback : Amount of signal reinjected in the loop (between -1 and 1).
pan : Position value between 0 and 1.
delayVar : Name of the control bus multiplying delay value.
feedbackVar : Name of the control bus multiplying feedback value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    dly = feed = amp = panval = ''
    vars = [delayVar, feedbackVar, amplitudeVar, panVar]
    delay, amplitude, starttime, duration, pan, input, feedback = _convertToList(delay, amplitude, starttime, duration,
                                                                                         pan, input, feedback)
    delayVar, amplitudeVar, panVar, feedbackVar = _convertVarToList(delayVar, amplitudeVar, panVar, feedbackVar)
    seq = max(len(input), len(delay), len(amplitude), len(starttime), len(duration), len(pan), len(feedback),
              _len(delayVar), _len(amplitudeVar), _len(panVar), _len(feedbackVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("afeed%s%d init 0\n" % (j, i))
                if not delayVar:
                    orchlines.append("a%s%d vdel abus%s%s+afeed%s%d, %s*1000, 10\n" % (j, i, j, _wrap(input,i), j, i, _wrap(delay,i)))
                else:
                    orchlines.append("amod%s%d interp kbus%s\n" % (j, i, _wrap(delayVar,i)))
                    orchlines.append("a%s%d vdelay3 abus%s%s+afeed%s%d, %s*amod%s%d*1000, 10000\n" % (j, i, j, _wrap(input,i), j, i, _wrap(delay,i), j, i))
                if not feedbackVar:
                    orchlines.append("afeed%s%d = a%s%d * %s\n"  % (j, i, j, i, _wrap(feedback,i)))
                else:
                    orchlines.append("afeed%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(feedback,i), _wrap(feedbackVar,i)))    
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('vdelay', int(_whichVars(vars) + offset))
    pval = 8
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if delayVar:
            pval, dly = _setadelVar(pval, 'dly')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p7-%d\n" % (j, voice))
            orchlines.append("afeed%d init 0\n" % j)
            orchlines.append("a%d vdelay3 ain%d + afeed%d, p4%s*1000, 10000\n" % (j, j, j, dly))
            orchlines.append("afeed%d = a%d * p6%s\n" % (j, j, feed))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'delay', 'amplitude', 'feedback', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if delayVar: paramDict[procNum][str(instrument)].append('delayVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(delay,i), _wrap(amplitude,i), _wrap(feedback,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if delayVar: line += "%s " % _kbusget(_wrap(delayVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if feedbackVar: line += "%s " % _kbusget(_wrap(feedbackVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def phaser(input, pitch=100, amplitude=1, duration=None, starttime=0, q=.5, feedback=.5, scale=1, order=10, mode=1, pan=0.5, pitchVar=None, qVar=None, feedbackVar=None, scaleVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Sound is passed through second-order allpass filters arranged in a series.

input = input_sound
pitch = 100 # Hz
amplitude = 1
duration = None
starttime = 0
q = .5
feedback = .5 # 0 -> 1
scale = 1
order = 10
mode = 1 # 1 or 2
pan = 0.5
pitchVar = None
qVar = None
feedbackVar = None
scaleVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
pitch : This is the center frequency of the notch of the first allpass filter in the series. This frequency is used as the base frequency from which the frequencies of the other notches are derived.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
q : Q of each notch. Higher Q values result in narrow notches.
feedback : Amount of signal reinjected in the allpass chain (between -1 and 1).
scale : Scaling factor used, in conjunction with imode, to determine the frequencies of the additional notches in the output spectrum. 
order : Number of allpass stages in series. 
mode : Used in calculation of notch frequencies. When mode = 1, notches are in harmonic relationship. When mode = 2, notches are in octave relationship.  
pan : Position value between 0 and 1.
pitchVar : Name of the control bus multiplying pitch value.
qVar : Name of the control bus multiplying q value.
feedbackVar : Name of the control bus multiplying feedback value.
scaleVar : Name of the control bus multiplying scale value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = cue = feed = scl = amp = panval = ''
    vars = [pitchVar, qVar, feedbackVar, scaleVar, amplitudeVar, panVar]
    pitch, amplitude, starttime, duration, pan, input, q, feedback, scale, order, mode = _convertToList(pitch, amplitude, starttime, duration,
                                                                                         pan, input, q, feedback, scale, order, mode)
    pitchVar, amplitudeVar, panVar, qVar, feedbackVar, scaleVar = _convertVarToList(pitchVar, amplitudeVar, panVar, qVar, feedbackVar, scaleVar)
    seq = max(len(input), len(pitch), len(amplitude), len(starttime), len(duration), len(pan), len(q), len(feedback), len(scale), len(order), len(mode),
              _len(pitchVar), _len(amplitudeVar), _len(panVar), _len(qVar), _len(feedbackVar), _len(scaleVar))
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d phaser2 abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(pitch,i)))
                if pitchVar:
                    orchlines.append("*kbus%s" % _wrap(pitchVar,i))
                orchlines.append(", %s" % _wrap(q,i))
                if qVar:
                    orchlines.append("*kbus%s" % _wrap(qVar,i))
                orchlines.append(", %s, %s, %s" % (_wrap(order,i), _wrap(mode,i), _wrap(scale,i)))
                if scaleVar:
                    orchlines.append("*kbus%s\n" % _wrap(scaleVar,i))
                orchlines.append(", %s" % _wrap(feedback,i))
                if feedbackVar:
                    orchlines.append("*kbus%s\n" % _wrap(feedbackVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('phaser', int(_whichVars(vars) + offset))
    pval = 12
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if qVar:
            pval, cue = _setxxxVar(pval, 'cue')
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if scaleVar:
            pval, scl = _setxxxVar(pval, 'scl')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\n" % (j, voice))
            orchlines.append("a%d phaser2 ain%d, p4%s, p6%s, p10, p11, p9%s, p7%s\n" % (j, j, pit, cue, scl, feed))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'pitch', 'amplitude', 'q', 'feedback', 'input', 'scale', 'order', 'mode']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if qVar: paramDict[procNum][str(instrument)].append('qVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    if scaleVar: paramDict[procNum][str(instrument)].append('scaleVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(pitch,i), _wrap(amplitude,i), _wrap(q,i), _wrap(feedback,i), str(ainput), _wrap(scale,i), _wrap(order,i), _wrap(mode,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if qVar: line += "%s " % _kbusget(_wrap(qVar,i))
        if feedbackVar: line += "%s " % _kbusget(_wrap(feedbackVar,i))
        if scaleVar: line += "%s " % _kbusget(_wrap(scaleVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def flanger(input, delay=.005, amplitude=1, duration=None, starttime=0, lfofreq=.1, lfoamp=.002, feedback=.5, pan=0.5, delayVar=None, lfofreqVar=None, lfoampVar=None, feedbackVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Generates harmonizing voices based on the audio signal.

input = input_sound
delay = 0.005 # seconds
amplitude = 1
duration = None
starttime = 0
lfofreq = 0.1 # Hz
lfoamp = 0.002
feedback = 0.5 # 0 -> 1
pan = 0.5
delayVar = None
lfofreqVar = None
lfoampVar = None
feedbackVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
delay : Average delay in seconds.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
lfofreq : Frequency of the low frequency oscillator modulating the delay.
lfoamp : Amplitude of the low frequency oscillator modulating the delay. Must be lower than delay / 2.
feedback : Amount of signal reinjected in the loop (between -1 and 1).
pan : Position value between 0 and 1.
delayVar : Name of the control bus multiplying delay value.
lfofreqVar : Name of the control bus multiplying lfofreq value.
lfoampVar : Name of the control bus multiplying lfoamp value.
feedbackVar : Name of the control bus multiplying feedback value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    dly = lff = lfa = feed = amp = panval = ''
    vars = [delayVar, lfofreqVar, lfoampVar, feedbackVar, amplitudeVar, panVar]
    delay, amplitude, starttime, duration, pan, input, lfofreq, lfoamp, feedback = _convertToList(delay, amplitude, starttime, duration,
                                                                                         pan, input, lfofreq, lfoamp, feedback)
    delayVar, amplitudeVar, panVar, lfofreqVar, lfoampVar, feedbackVar = _convertVarToList(delayVar, amplitudeVar, panVar, lfofreqVar, lfoampVar, feedbackVar)
    seq = max(len(input), len(delay), len(amplitude), len(starttime), len(duration), len(pan), len(lfofreq), len(feedback), len(lfoamp),
              _len(delayVar), _len(amplitudeVar), _len(panVar), _len(lfofreqVar), _len(feedbackVar), _len(lfoampVar))
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("alf%s%d oscili %s" % (j, i, _wrap(lfoamp,i)))
                if lfoampVar:
                    orchlines.append("*kbus%s" % _wrap(lfoampVar,i))
                orchlines.append(", %s" % _wrap(lfofreq,i))
                if lfofreqVar:
                    orchlines.append("*kbus%s, 1\n" % _wrap(lfofreqVar,i))
                else:
                    orchlines.append(", 1\n")
                orchlines.append("a%s%d flanger abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(delay,i)))
                if delayVar:
                    orchlines.append("*kbus%s" % _wrap(delayVar,i))
                orchlines.append("+alf%s%d, %s" % (j, i, _wrap(feedback,i)))
                if feedbackVar:
                    orchlines.append("*kbus%s\n" % _wrap(feedbackVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('flanger', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if delayVar:
            pval, dly = _setxxxVar(pval, 'dly')
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if lfofreqVar:
            pval, lff = _setxxxVar(pval, 'lff')
        if lfoampVar:
            pval, lfa = _setxxxVar(pval, 'lfa')
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p9-%d\n" % (j, voice))
            orchlines.append("alf%d oscili p7%s, p6%s, 1\n" % (j, lfa, lff))
            orchlines.append("a%d flanger ain%d, p4%s+alf%d, p8%s\n" % (j, j, dly, j, feed))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'delay', 'amplitude', 'lfofreq', 'lfoamp', 'feedback', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if delayVar: paramDict[procNum][str(instrument)].append('delayVar')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if lfofreqVar: paramDict[procNum][str(instrument)].append('lfofreqVar')
    if lfoampVar: paramDict[procNum][str(instrument)].append('lfoampVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(delay,i), _wrap(amplitude,i), _wrap(lfofreq,i), _wrap(lfoamp,i), _wrap(feedback,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if delayVar: line += "%s " % _kbusget(_wrap(delayVar,i))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if lfofreqVar: line += "%s " % _kbusget(_wrap(lfofreqVar,i))
        if lfoampVar: line += "%s " % _kbusget(_wrap(lfoampVar,i))
        if feedbackVar: line += "%s " % _kbusget(_wrap(feedbackVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def vocoder(in1, in2, amplitude=1, duration=None, starttime=0, minfreq=200, maxfreq=5000, q=20, bands=32, pan=0.5, minfreqVar=None, maxfreqVar=None, qVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Applies the analysed spectral envelope of a sound to an excitation signal.

in1 = exication_input
in2 = analysis_input
amplitude = 1
duration = None
starttime = 0
minfreq = 200
maxfreq = 5000
q = 20
bands = 32
pan = 0.5
minfreqVar = None
maxfreqVar = None
qVar = None
amplitudeVar = None
panVar = None
out = 'dac'

* vocoder opcode by Victor Lazzarini"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    mif = maf = cue = amp = panval = ''
    vars = [minfreqVar, maxfreqVar, qVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, in1, in2, minfreq, maxfreq, q, bands = _convertToList(amplitude, starttime, duration, pan, in1, in2, minfreq, maxfreq, q, bands)
    minfreqVar, maxfreqVar, qVar, amplitudeVar, panVar = _convertVarToList(minfreqVar, maxfreqVar, qVar, amplitudeVar, panVar)
    seq = max(len(in1), len(in2), len(amplitude), len(starttime), len(duration), len(pan), len(minfreq), len(maxfreq), len(q), len(bands), _len(amplitudeVar), _len(panVar),
              _len(minfreqVar), _len(maxfreqVar), _len(qVar))

    if not 'vocoder' in UDO:
        UDO.append('vocoder')

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d vocoder abus%s%s, abus%s%s, %s" % (j, i, j, _wrap(in1,i), j, _wrap(in2,i), _wrap(minfreq,i)))
                if minfreqVar:
                    orchlines.append("*kbus%s" % _wrap(minfreqVar,i))
                orchlines.append(", %s" % _wrap(maxfreq,i))
                if maxfreqVar:
                    orchlines.append("*kbus%s" % _wrap(maxfreqVar,i))
                orchlines.append(", %s" % _wrap(q,i))
                if qVar:
                    orchlines.append("*kbus%s" % _wrap(qVar,i))
                orchlines.append(", %s\n" % _wrap(bands,i))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*%s*kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d*%s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('ringMod', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if minfreqVar:
            pval, mif = _setxxxVar(pval, 'mif')
        if maxfreqVar:
            pval, maf = _setxxxVar(pval, 'maf')
        if qVar:
            pval, cue = _setxxxVar(pval, 'cue')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            num = j
            num2 = num + _checkChannels()
            voice = _checkChannels() - (j + 1)
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
            orchlines.append("ain%d zar p6-%d\n" % (num2, voice))
            orchlines.append("a%d vocoder ain%d, ain%d, p7%s, p8%s, p9%s, p10\n" % (num, num, num2, mif, maf, cue))
            orchlines.append("a%d = a%d * p5%s\n" % (num, num, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'in1', 'amplitude', 'in2', 'minfreq', 'maxfreq', 'q', 'bands']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if minfreqVar: paramDict[procNum][str(instrument)].append('minfreqVar')
    if maxfreqVar: paramDict[procNum][str(instrument)].append('maxfreqVar')
    if qVar: paramDict[procNum][str(instrument)].append('qVar')
    for i in range(seq):
        ainput = _zakget(in1[i%len(in1)])
        ainput2 = _zakget(in2[i%len(in2)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), str(ainput2), _wrap(minfreq,i), _wrap(maxfreq,i), _wrap(q,i), _wrap(bands,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if minfreqVar: line += "%s " % _kbusget(_wrap(minfreqVar,i))
        if maxfreqVar: line += "%s " % _kbusget(_wrap(maxfreqVar,i))
        if qVar: line += "%s " % _kbusget(_wrap(qVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

###############################################
############# Filters instruments #############
def lowpass(input, amplitude=1, duration=None, starttime=0, cutoff=6000, pan=0.5, cutoffVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Filter the audio signal with a butterworth lowpass filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
pan = 0.5
cutoffVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Cutoff frequency, in Hertz, of the filter. 
pan : Position value between 0 and 1.
cutoffVar : Name of the control bus multiplying cutoff value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = amp = panval = ''
    vars = [cutoffVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff = _convertToList(amplitude, starttime, duration, pan, input, cutoff)
    amplitudeVar, panVar, cutoffVar = _convertVarToList(amplitudeVar, panVar, cutoffVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), _len(cutoffVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d butterlp abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('lowpass', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p6-%d\na%d butterlp ain%d, p4%s\n" % (j, voice, j, j, cut))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
    
def highpass(input, amplitude=1, duration=None, starttime=0, cutoff=6000, pan=0.5, cutoffVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Filter the audio signal with a butterworth highpass filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
pan = 0.5
cutoffVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Cutoff frequency, in Hertz, of the filter. 
pan : Position value between 0 and 1.
cutoffVar : Name of the control bus multiplying cutoff value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = amp = panval = ''
    vars = [cutoffVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff = _convertToList(amplitude, starttime, duration, pan, input, cutoff)
    amplitudeVar, panVar, cutoffVar = _convertVarToList(amplitudeVar, panVar, cutoffVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), _len(cutoffVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d butterhp abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('highpass', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p6-%d\na%d butterhp ain%d, p4%s\n" % (j, voice, j, j, cut))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def bandpass(input, amplitude=1, duration=None, starttime=0, cutoff=6000, bandwidth=1000, pan=0.5, cutoffVar=None, bandwidthVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Filter the audio signal with a butterworth bandpass filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
bandwidth = 1000
pan = 0.5
cutoffVar = None
bandwidthVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Center frequency, in Hertz, of the filter. 
bandwidth : Bandwidth, in Hertz,  of the filter.
pan : Position value between 0 and 1.
cutoffVar : Name of the control bus multiplying cutoff value.
bandwidthVar : Name of the control bus multiplying bandwidth value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = band = amp = panval = ''
    vars = [cutoffVar, bandwidthVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff, bandwidth = _convertToList(amplitude, starttime, duration, pan, input, cutoff, bandwidth)
    amplitudeVar, panVar, cutoffVar, bandwidthVar = _convertVarToList(amplitudeVar, panVar, cutoffVar, bandwidthVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), len(bandwidth), _len(cutoffVar), _len(bandwidthVar),
              _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d butterbp abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                orchlines.append(", %s" % str(bandwidth[i%len(bandwidth)]))
                if bandwidthVar:
                    orchlines.append("*kbus%s\n" % str(bandwidthVar[i%len(bandwidthVar)]))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('bandpass', int(_whichVars(vars) + offset))
    pval = 8
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if bandwidthVar:
            pval, band = _setxxxVar(pval, 'band')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p7-%d\na%d butterbp ain%d, p4%s, p5%s\n" % (j, voice, j, j, cut, band))
            orchlines.append("a%d = a%d*p6%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'bandwidth', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if bandwidthVar: paramDict[procNum][str(instrument)].append('bandwidthVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), str(bandwidth[i%len(bandwidth)]), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if bandwidthVar: line += "%s " % str(_kbusget(bandwidthVar[i%len(bandwidthVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def bandreject(input, amplitude=1, duration=None, starttime=0, cutoff=6000, bandwidth=1000, pan=0.5, cutoffVar=None, bandwidthVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Filter the audio signal with a butterworth bandreject filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
bandwidth = 1000
pan = 0.5
cutoffVar = None
bandwidthVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Center frequency, in Hertz, of the filter. 
bandwidth : Bandwidth, in Hertz,  of the filter.
pan : Position value between 0 and 1.
cutoffVar : Name of the control bus multiplying cutoff value.
bandwidthVar : Name of the control bus multiplying bandwidth value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = band = amp = panval = ''
    vars = [cutoffVar, bandwidthVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff, bandwidth = _convertToList(amplitude, starttime, duration, pan, input, cutoff, bandwidth)
    amplitudeVar, panVar, cutoffVar, bandwidthVar = _convertVarToList(amplitudeVar, panVar, cutoffVar, bandwidthVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), len(bandwidth), _len(cutoffVar), _len(bandwidthVar),
              _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d butterbr abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                orchlines.append(", %s" % str(bandwidth[i%len(bandwidth)]))
                if bandwidthVar:
                    orchlines.append("*kbus%s\n" % str(bandwidthVar[i%len(bandwidthVar)]))
                else:
                    orchlines.append("\n")
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('bandreject', int(_whichVars(vars) + offset))
    pval = 8
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if bandwidthVar:
            pval, band = _setxxxVar(pval, 'band')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p7-%d\na%d butterbr ain%d, p4%s, p5%s\n" % (j, voice, j, j, cut, band))
            orchlines.append("a%d = a%d*p6%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'bandwidth', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if bandwidthVar: paramDict[procNum][str(instrument)].append('bandwidthVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), str(bandwidth[i%len(bandwidth)]), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if bandwidthVar: line += "%s " % str(_kbusget(bandwidthVar[i%len(bandwidthVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def resFilter(input, amplitude=1, duration=None, starttime=0, cutoff=6000, resonance=1, mode=0, pan=0.5, cutoffVar=None, resonanceVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Filter the audio signal with a second-order multi-mode filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
resonance = 1 # 1 -> 100
mode = 0
pan = 0.5
cutoffVar = None
resonanceVar = None
amplitudeVar = None
panVar = None
out = 'dac'

modes: 
0 = lowpass
1 = highpass
2 = bandpass
3 = bandreject
4 = allpass"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = res = amp = panval = ''
    vars = [cutoffVar, resonanceVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff, resonance, mode = _convertToList(amplitude, starttime, duration, pan, input, cutoff, resonance, mode)
    amplitudeVar, panVar, cutoffVar, resonanceVar = _convertVarToList(amplitudeVar, panVar, cutoffVar, resonanceVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), len(resonance), len(mode), _len(cutoffVar), _len(resonanceVar),
              _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d bqrez abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                orchlines.append(", %s" % _wrap(resonance,i))
                if resonanceVar:
                    orchlines.append("*kbus%s\n" % _wrap(resonanceVar,i))
                orchlines.append(", %s\n" % _wrap(mode,i))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('resFilter', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if resonanceVar:
            pval, res = _setxxxVar(pval, 'res')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p7-%d\na%d bqrez ain%d, p4%s, p5%s, p8\n" % (j, voice, j, j, cut, res))
            orchlines.append("a%d = a%d*p6%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'resonance', 'amplitude', 'input', 'mode']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if resonanceVar: paramDict[procNum][str(instrument)].append('resonanceVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), _wrap(resonance,i), _wrap(amplitude,i), str(ainput), _wrap(mode,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if resonanceVar: line += "%s " % _kbusget(_wrap(resonanceVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def eqFilter(input, amplitude=1, duration=None, starttime=0, cutoff=6000, boost=1, q=0.707, mode=0, pan=0.5, cutoffVar=None, boostVar=None, qVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Peaking, low shelving or high shelving filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
cutoff = 6000
boost = 1 # cut < 1 < boost
q = 0.707 # sqrt(0.5) is no resonance
mode = 0
pan = 0.5
cutoffVar = None
boostVar = None
qVar = None
amplitudeVar = None
panVar = None
out = 'dac'

modes: 
0 = peaking
1 = Low Shelving
2 = High Shelving
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = boo = cue = amp = panval = ''
    vars = [cutoffVar, boostVar, qVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff, boost, q, mode = _convertToList(amplitude, starttime, duration, pan, input, cutoff, boost, q, mode)
    amplitudeVar, panVar, cutoffVar, boostVar, qVar = _convertVarToList(amplitudeVar, panVar, cutoffVar, boostVar, qVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(cutoff), len(boost), len(q), len(mode), _len(cutoffVar), _len(qVar),
              _len(boostVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d pareq abus%s%s, %s" % (j, i, j, _wrap(input,i), _wrap(cutoff,i)))
                if cutoffVar:
                    orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                orchlines.append(", %s" % _wrap(boost,i))
                if boostVar:
                    orchlines.append("*kbus%s\n" % _wrap(boostVar,i))
                orchlines.append(", %s" % _wrap(q,i))
                if qVar:
                    orchlines.append("*kbus%s\n" % _wrap(qVar,i))
                orchlines.append(", %s\n" % _wrap(mode,i))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('eqFilter', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if boostVar:
            pval, boo = _setxxxVar(pval, 'boo')
        if qVar:
            pval, cue = _setxxxVar(pval, 'cue')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p8-%d\na%d pareq ain%d, p4%s, p5%s, p6%s, p9\n" % (j, voice, j, j, cut, boo, cue))
            orchlines.append("a%d = a%d*p7%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'cutoff', 'boost', 'q', 'amplitude', 'input', 'mode']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if boostVar: paramDict[procNum][str(instrument)].append('boostVar')
    if qVar: paramDict[procNum][str(instrument)].append('qVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(cutoff,i), _wrap(boost,i), _wrap(q,i), _wrap(amplitude,i), str(ainput), _wrap(mode,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if boostVar: line += "%s " % _kbusget(_wrap(boostVar,i))
        if qVar: line += "%s " % _kbusget(_wrap(qVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
  
def dcblock(input, amplitude=1, duration=None, starttime=0, pan=0.5, amplitudeVar=None, panVar=None, out='dac'):
    """A DC blocking filter.

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input = _convertToList(amplitude, starttime, duration, pan, input)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d dcblock abus%s%s\n" % (j, i, j, _wrap(input,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('dcblock', int(_whichVars(vars) + offset))
    pval = 6
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p5-%d\na%d dcblock ain%d\n" % (j, voice, j, j))
            orchlines.append("a%d = a%d*p4%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

###############################################
######### Spectral effects instruments ########
def blur(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, blurtime=.1, blurtimeVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Blurs the sound by smoothing the amplitude and frequency time functions. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
blurtime = 0.1 # 0 -> 1 seconds
blurtimeVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    blu = amp = panval = ''
    vars = [blurtimeVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, blurtime = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, blurtime)
    amplitudeVar, panVar, blurtimeVar = _convertVarToList(amplitudeVar, panVar, blurtimeVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(blurtime),
              _len(amplitudeVar), _len(panVar), _len(blurtimeVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                if not blurtimeVar:
                    orchlines.append("fblur%s pvsblur fsig%s, %s, 1\n" % (j, j, _wrap(blurtime,i)))
                else:
                    orchlines.append("fblur%s pvsblur fsig%s, %s*kbus%s, 1\n" % (j, j, _wrap(blurtime,i), _wrap(blurtimeVar,i)))
                orchlines.append("a%s%d pvsynth fblur%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('blur', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if blurtimeVar:
            pval, blu = _setxxxVar(pval, 'blu')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fblur%d pvsblur fsig%d, p9%s, 1\n" % (j, j, blu))
            orchlines.append("a%d pvsynth fblur%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'blurtime']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if blurtimeVar: paramDict[procNum][str(instrument)].append('blurtimeVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(blurtime,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if blurtimeVar: line += "%s " % _kbusget(_wrap(blurtimeVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def smooth(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, smoothamp=.1, smoothfreq=1, smoothampVar=None, smoothfreqVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Blurs the sound by smoothing the amplitude and frequency time functions. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
smoothamp = 0.1 # 0 (very long) -> 1 (no smooth)
smoothfreq = 1 # 0 (very long) -> 1 (no smooth)
smoothampVar = None
smoothfreqVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    smoa = smof = amp = panval = ''
    vars = [smoothampVar, smoothfreqVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, smoothamp, smoothfreq = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, smoothamp, smoothfreq)
    amplitudeVar, panVar, smoothampVar, smoothfreqVar = _convertVarToList(amplitudeVar, panVar, smoothampVar, smoothfreqVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(smoothamp),
              len(smoothfreq), _len(amplitudeVar), _len(panVar), _len(smoothampVar), _len(smoothfreqVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("fsmooth%s pvsmooth fsig%s, %s" % (j, j, _wrap(smoothamp,i)))
                if smoothampVar:
                    orchlines.append("*kbus%s" % _wrap(smoothampVar,i))
                orchlines.append(", %s" % _wrap(smoothfreq,i))
                if smoothfreqVar:
                    orchlines.append("*kbus%s\n" % _wrap(smoothfreqVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("a%s%d pvsynth fsmooth%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('smooth', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if smoothampVar:
            pval, smoa = _setxxxVar(pval, 'smoa')
        if smoothfreqVar:
            pval, smof = _setxxxVar(pval, 'smof')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fsmooth%d pvsmooth fsig%d, p9%s, p10%s\n" % (j, j, smoa, smof))
            orchlines.append("a%d pvsynth fsmooth%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'smoothamp', 'smoothfreq']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if smoothampVar: paramDict[procNum][str(instrument)].append('smoothampVar')
    if smoothfreqVar: paramDict[procNum][str(instrument)].append('smoothfreqVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(smoothamp,i), _wrap(smoothfreq,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if smoothampVar: line += "%s " % _kbusget(_wrap(smoothampVar,i))
        if smoothfreqVar: line += "%s " % _kbusget(_wrap(smoothfreqVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
 
def freeze(input, triggerbus, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, amplitudeVar=None, panVar=None, out='dac'):
    """Freezes the amplitude and frequency time functions. 

input = input_sound
triggerbus = controller_bus # freeze is 'on' if equal to or above 1 and 'off' if below 1
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    fre = amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, triggerbus = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, triggerbus)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(triggerbus),
              _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("ffreeze%s pvsfreeze fsig%s, kbus%s, kbus%s\n" % (j, j, _wrap(triggerbus,i), _wrap(triggerbus,i)))
                orchlines.append("a%s%d pvsynth fblur%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('freeze', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        orchlines.append('Sfreezekbus sprintf "kbus%d"')
        orchlines.append(", p%d\n" % pval)
        orchlines.append("kfreeze chnget Sfreezekbus\n")
        pval += 1
        fre = 'kfreeze'
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("ffreeze%d pvsfreeze fsig%d, %s, %s\n" % (j, j, fre, fre))
            orchlines.append("a%d pvsynth ffreeze%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'triggerbus']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _kbusget(_wrap(triggerbus,i)))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def crossSynth(in1, in2, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, cross=1, crossVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Performs cross synthesis.

in1 = first_input
in2 = second_input
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
cross = 1
crossVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cros1 = cros2 = amp = panval = ''
    vars = [crossVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, in1, in2, fftsize, overlaps, windowsize, cross = _convertToList(amplitude, starttime, duration,
                                                                                    pan, in1, in2, fftsize, overlaps, windowsize, cross)
    amplitudeVar, panVar, crossVar = _convertVarToList(amplitudeVar, panVar, crossVar)
    seq = max(len(in1), len(in2), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(cross),
              _len(amplitudeVar), _len(panVar), _len(crossVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s1 pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, str(in1[i%len(in1)]), _wrap(amplitude,i), str(fftsize[i%len(fftsize)]), str(fftsize[i%len(fftsize)]), str(overlaps[i%len(overlaps)]), str(windowsize[i%len(windowsize)])))
                orchlines.append("fsig%s2 pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, str(in2[i%len(in2)]), _wrap(amplitude,i), str(fftsize[i%len(fftsize)]), str(fftsize[i%len(fftsize)]), str(overlaps[i%len(overlaps)]), str(windowsize[i%len(windowsize)])))
                if not crossVar:
                    orchlines.append("fcross%s pvscross fsig%s1, fsig%s2, (1-%s), %s\n" % (j, j, j, str(cross[i%len(cross)]), str(cross[i%len(cross)])))
                else:
                    orchlines.append("fcross%s pvscross fsig%s1, fsig%s2, (1-%s)*(1-kbus%s), %s*kbus%s\n" % (j, j, j, str(cross[i%len(cross)]), str(crossVar[i%len(crossVar)]), str(cross[i%len(cross)]), str(crossVar[i%len(crossVar)])))
                orchlines.append("a%s%d pvsynth fcross%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('crossSynth', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if crossVar:
            orchlines.append('Scroskbus sprintf "kbus%d"')
            orchlines.append(", p%d\n" % pval)
            orchlines.append("kcross chnget Scroskbus\n")
            pval += 1
            cros1 = '*(1-kcross)'
            cros2 = '*kcross'
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            num = j
            num2 = num + _checkChannels()
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (num, voice))
            orchlines.append("ain%d zar p10-%d\n" % (num2, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (num, num))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (num2, num2))
            orchlines.append("fcross%d pvscross fsig%d, fsig%d, (1-p9)%s, p9%s\n" % (num, num, num2, cros1, cros2))
            orchlines.append("a%d pvsynth fcross%d\n" % (num, num))
            orchlines.append("a%d = a%d*p5%s\n" % (num, num, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'in1', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'cross', 'in2']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if crossVar: paramDict[procNum][str(instrument)].append('crossVar')
    for i in range(seq):
        ainput = _zakget(in1[i%len(in1)])
        ainput2 = _zakget(in2[i%len(in2)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), str(fftsize[i%len(fftsize)]), str(overlaps[i%len(overlaps)]), str(windowsize[i%len(windowsize)]), str(cross[i%len(cross)]), str(ainput2))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if crossVar: line += "%s " % str(_kbusget(crossVar[i%len(crossVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def transpose(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, transpo=.5, keepformant=0, transpoVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Scale the frequency components of a sound. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
transpo = 0.5 # ratio (1 -> unchanged)
keepformant = 0 # 0, 1 or 2
transpoVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    trans = amp = panval = ''
    vars = [transpoVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, transpo, keepformant = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, transpo, keepformant)
    amplitudeVar, panVar, transpoVar = _convertVarToList(amplitudeVar, panVar, transpoVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(transpo), len(keepformant),
              _len(amplitudeVar), _len(panVar), _len(transpoVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                if not transpoVar:
                    orchlines.append("fscale%s pvscale fsig%s, %s, %s\n" % (j, j, _wrap(tranpo,i), _wrap(keepformant,i)))
                else:
                    orchlines.append("fscale%s pvscale fsig%s, %s*kbus%s, %s\n" % (j, j, _wrap(transpo,i), _wrap(transpoVar,i), _wrap(keepformant,i)))
                orchlines.append("a%s%d pvsynth fscale%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('transpose', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if transpoVar:
            pval, trans = _setxxxVar(pval, 'trans')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fscale%d pvscale fsig%d, p9%s, p10\n" % (j, j, trans))
            orchlines.append("a%d pvsynth fscale%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'transpo', 'keepformant']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if transpoVar: paramDict[procNum][str(instrument)].append('transpoVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(transpo,i), _wrap(keepformant,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if transpoVar: line += "%s " % _kbusget(_wrap(transpoVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def arpegiator(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, bin=.1, attenuation=1, boost=1, binVar=None, attenuationVar=None, boostVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Arpeggiates the spectral components of a sound. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
bin = 0.1 # target bin (normalized between 0 -> 1)
attenuation = 1 # depth of attenuation of surrounding bins
boost = 1 # gain boost applied to the target bin
binVar = None
attenuationVar = None
boostVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    bi = att = boo = amp = panval = ''
    vars = [binVar, attenuationVar, boostVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, bin, attenuation, boost = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, bin, attenuation, boost)
    amplitudeVar, panVar, binVar, attenuationVar, boostVar = _convertVarToList(amplitudeVar, panVar, binVar, attenuationVar, boostVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(bin), len(boost),
              len(attenuation), _len(amplitudeVar), _len(panVar), _len(binVar), _len(attenuationVar), _len(boostVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("farp%s pvsarp fsig%s, %s" % (j, j, _wrap(bin,i)))
                if binVar:
                    orchlines.append("*kbus%s" % _wrap(binVar,i))
                orchlines.append(", %s" % _wrap(attenuation,i))
                if attenuationVar:
                    orchlines.append("*kbus%s\n" % _wrap(attenuationVar,i))
                orchlines.append(", %s" % _wrap(boost,i))
                if boostVar:
                    orchlines.append("*kbus%s\n" % _wrap(boostVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("a%s%d pvsynth farp%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('arpegiator', int(_whichVars(vars) + offset))
    pval = 12
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if binVar:
            pval, bi = _setxxxVar(pval, 'bi')
        if attenuationVar:
            pval, att = _setxxxVar(pval, 'att')
        if boostVar:
            pval, boo = _setxxxVar(pval, 'boo')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("farp%d pvsarp fsig%d, p9%s, p10%s, p11%s\n" % (j, j, bi, att, boo))
            orchlines.append("a%d pvsynth farp%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'bin', 'attenuation', 'boost']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if binVar: paramDict[procNum][str(instrument)].append('binVar')
    if attenuationVar: paramDict[procNum][str(instrument)].append('attenuationVar')
    if boostVar: paramDict[procNum][str(instrument)].append('boostVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(bin,i), _wrap(attenuation,i), _wrap(boost,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if binVar: line += "%s " % _kbusget(_wrap(binVar,i))
        if attenuationVar: line += "%s " % _kbusget(_wrap(attenuationVar,i))
        if boostVar: line += "%s " % _kbusget(_wrap(boostVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def reSynth(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, numoscs=50, binoffset=0, binincr=5, pitch=1, pitchVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Resynthesize a sound using a fast oscillator-bank. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
numoscs = 50 # (1 -> fftsize/2)
binoffset = 0 # first bin to synthesize
binincr = 5 # step between synthesized bins
pitch = 1
pitchVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    pit = amp = panval = ''
    vars = [pitchVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, numoscs, binoffset, binincr, pitch = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize,  numoscs, binoffset, binincr, pitch)
    amplitudeVar, panVar, pitchVar = _convertVarToList(amplitudeVar, panVar, pitchVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(pitch), len(numoscs), len(binoffset), len(binincr),
              _len(amplitudeVar), _len(panVar), _len(pitchVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                if not pitchVar:
                    orchlines.append("fsynth%s pvsadsyn fsig%s, %s %s, %s, %s\n" % (j, j, _wrap(numosc,i), _wrap(pitch,i), _wrap(binoffset,1), _wrap(binincr,i)))
                else:
                    orchlines.append("a%s%d pvsadsyn fsig%s, %s, %s*kbus%s, %s, %s\n" % (j, i, j, _wrap(numoscs), _wrap(pitch,i), _wrap(pitchVar,i), _wrap(binoffset,1), _wrap(binincr,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('reSynth', int(_whichVars(vars) + offset))
    pval = 13
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if pitchVar:
            pval, pit = _setxxxVar(pval, 'pit')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("a%d pvsadsyn fsig%d, p10, p9%s, p11, p12\n" % (j, j, pit))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'pitch', 'numoscs', 'binoffset', 'binincr']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if pitchVar: paramDict[procNum][str(instrument)].append('pitchVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(pitch,i), _wrap(numoscs,i), _wrap(binoffset,i), _wrap(binincr,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if pitchVar: line += "%s " % _kbusget(_wrap(pitchVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)
 
def maskFilter(input, table, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, attenuation=1, attenuationVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Modify amplitudes using a function table, with dynamic scaling. 

input = input_sound
table = table_number
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
attenuation = 1 # (0 = unchanged, 0 = full profile)
attenuationVar = None
amplitudeVar = None
panVar = None
out = 'dac'

table size must be fftsize/2 or higher."""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    att = amp = panval = ''
    vars = [attenuationVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, attenuation, table = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, attenuation, table)
    amplitudeVar, panVar, attenuationVar = _convertVarToList(amplitudeVar, panVar, attenuationVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(attenuation), len(table),
              _len(amplitudeVar), _len(panVar), _len(attenuationVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                if not attenuationVar:
                    orchlines.append("fmask%s pvsmaska fsig%s, %s, %s\n" % (j, j, _wrap(table,i), _wrap(attenuation,i)))
                else:
                    orchlines.append("fmask%s pvsmaska fsig%s, %s, %s*kbus%s\n" % (j, j,  _wrap(table,i), _wrap(attenuation,i), _wrap(attenuationVar,i)))
                orchlines.append("a%s%d pvsynth fscale%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('maskFilter', int(_whichVars(vars) + offset))
    pval = 11
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if attenuationVar:
            pval, att = _setxxxVar(pval, 'att')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fmask%d pvsmaska fsig%d, p10, p9%s\n" % (j, j, att))
            orchlines.append("a%d pvsynth fmask%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'attenuation', 'table']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if attenuationVar: paramDict[procNum][str(instrument)].append('attenuationVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(attenuation,i), _wrap(table,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if attenuationVar: line += "%s " % _kbusget(_wrap(attenuationVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fftBandpass(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, lowstart=400, lowend=500, highstart=2000, highend=2500, slope=0, 
                lowstartVar=None, lowendVar=None, highstartVar=None, highendVar=None, slopeVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """A band pass filter working in the spectral domain. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
lowstart = 400 # hertz
lowend = 500 # hertz
highstart = 2000 # hertz
highend = 2500 # hertz
slope = 0 # (0 -> 2.3)
lowstartVar = None
lowendVar = None
highstartVar = None
highendVar = None
slopeVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

slope : specifies the shape of the transitional band. At the default value of zero the shape is linear transition in amplitude. Other values yield and exponential shape. A linear dB shape is obtain when slope is log(10) or about 2.30 .
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    ls = le = hs = he = sl = amp = panval = ''
    vars = [lowstartVar, lowendVar, highstartVar, highendVar, slopeVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, lowstart, lowend, highstart, highend, slope = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, lowstart, lowend, highstart, highend, slope)
    amplitudeVar, panVar, lowstartVar, lowendVar, highstartVar, highendVar, slopeVar = _convertVarToList(amplitudeVar, panVar, lowstartVar, lowendVar, highstartVar, highendVar, slopeVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(lowstart), len(highstart), len(highend), len(slope),
              len(lowend), _len(amplitudeVar), _len(panVar), _len(lowstartVar), _len(lowendVar), _len(highstartVar), _len(highendVar), _len(slopeVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("fbandp%s pvsbandp fsig%s, %s" % (j, j, _wrap(lowstart,i)))
                if lowstartVar:
                    orchlines.append("*kbus%s" % _wrap(lowstartVar,i))
                orchlines.append(", %s" % _wrap(lowend,i))
                if lowendVar:
                    orchlines.append("*kbus%s" % _wrap(lowendVar,i))
                orchlines.append(", %s" % _wrap(highstart,i))
                if highstartVar:
                    orchlines.append("*kbus%s" % _wrap(highstartVar,i))
                orchlines.append(", %s" % _wrap(highend,i))
                if highendVar:
                    orchlines.append("*kbus%s" % _wrap(highendVar,i))
                orchlines.append(", %s" % _wrap(slope,i))
                if slopeVar:
                    orchlines.append("*kbus%s\n" % _wrap(slopeVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("a%s%d pvsynth fbandp%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fftBandpass', int(_whichVars(vars) + offset))
    pval = 14
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if lowstartVar:
            pval, ls = _setxxxVar(pval, 'ls')
        if lowendVar:
            pval, le = _setxxxVar(pval, 'le')
        if highstartVar:
            pval, hs = _setxxxVar(pval, 'hs')
        if highendVar:
            pval, he = _setxxxVar(pval, 'he')
        if slopeVar:
            pval, sl = _setxxxVar(pval, 'sl')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fbandp%d pvsbandp fsig%d, p9%s, p10%s, p11%s, p12%s, p13%s\n" % (j, j, ls, le, hs, he, sl))
            orchlines.append("a%d pvsynth fbandp%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'lowstart', 'lowend', 'highstart', 'highend', 'slope']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if lowstartVar: paramDict[procNum][str(instrument)].append('lowstartVar')
    if lowendVar: paramDict[procNum][str(instrument)].append('lowendVar')
    if highstartVar: paramDict[procNum][str(instrument)].append('highstartVar')
    if highendVar: paramDict[procNum][str(instrument)].append('highendVar')
    if slopeVar: paramDict[procNum][str(instrument)].append('slopeVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(lowstart,i), _wrap(lowend,i), _wrap(highstart,i), _wrap(highend,i), _wrap(slope,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if lowstartVar: line += "%s " % _kbusget(_wrap(lowstartVar,i))
        if lowendVar: line += "%s " % _kbusget(_wrap(lowendVar,i))
        if highstartVar: line += "%s " % _kbusget(_wrap(highstartVar,i))
        if highendVar: line += "%s " % _kbusget(_wrap(highendVar,i))
        if slopeVar: line += "%s " % _kbusget(_wrap(slopeVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fftBandreject(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, lowstart=400, lowend=500, highstart=2000, highend=2500, slope=0, 
                lowstartVar=None, lowendVar=None, highstartVar=None, highendVar=None, slopeVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """A band reject filter working in the spectral domain. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
lowstart = 400 # hertz
lowend = 500 # hertz
highstart = 2000 # hertz
highend = 2500 # hertz
slope = 0 # (0 -> 2.3)
lowstartVar = None
lowendVar = None
highstartVar = None
highendVar = None
slopeVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

slope : specifies the shape of the transitional band. At the default value of zero the shape is linear transition in amplitude. Other values yield and exponential shape. A linear dB shape is obtain when slope is log(10) or about 2.30 .
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    ls = le = hs = he = sl = amp = panval = ''
    vars = [lowstartVar, lowendVar, highstartVar, highendVar, slopeVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, lowstart, lowend, highstart, highend, slope = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, lowstart, lowend, highstart, highend, slope)
    amplitudeVar, panVar, lowstartVar, lowendVar, highstartVar, highendVar, slopeVar = _convertVarToList(amplitudeVar, panVar, lowstartVar, lowendVar, highstartVar, highendVar, slopeVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(lowstart), len(highstart), len(highend), len(slope),
              len(lowend), _len(amplitudeVar), _len(panVar), _len(lowstartVar), _len(lowendVar), _len(highstartVar), _len(highendVar), _len(slopeVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("fbandr%s pvsbandr fsig%s, %s" % (j, j, _wrap(lowstart,i)))
                if lowstartVar:
                    orchlines.append("*kbus%s" % _wrap(lowstartVar,i))
                orchlines.append(", %s" % _wrap(lowend,i))
                if lowendVar:
                    orchlines.append("*kbus%s" % _wrap(lowendVar,i))
                orchlines.append(", %s" % _wrap(highstart,i))
                if highstartVar:
                    orchlines.append("*kbus%s" % _wrap(highstartVar,i))
                orchlines.append(", %s" % _wrap(highend,i))
                if highendVar:
                    orchlines.append("*kbus%s" % _wrap(highendVar,i))
                orchlines.append(", %s" % _wrap(slope,i))
                if slopeVar:
                    orchlines.append("*kbus%s\n" % _wrap(slopeVar,i))
                else:
                    orchlines.append("\n")
                orchlines.append("a%s%d pvsynth fbandr%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fftBandreject', int(_whichVars(vars) + offset))
    pval = 14
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if lowstartVar:
            pval, ls = _setxxxVar(pval, 'ls')
        if lowendVar:
            pval, le = _setxxxVar(pval, 'le')
        if highstartVar:
            pval, hs = _setxxxVar(pval, 'hs')
        if highendVar:
            pval, he = _setxxxVar(pval, 'he')
        if slopeVar:
            pval, sl = _setxxxVar(pval, 'sl')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("fbandr%d pvsbandr fsig%d, p9%s, p10%s, p11%s, p12%s, p13%s\n" % (j, j, ls, le, hs, he, sl))
            orchlines.append("a%d pvsynth fbandr%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'lowstart', 'lowend', 'highstart', 'highend', 'slope']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if lowstartVar: paramDict[procNum][str(instrument)].append('lowstartVar')
    if lowendVar: paramDict[procNum][str(instrument)].append('lowendVar')
    if highstartVar: paramDict[procNum][str(instrument)].append('highstartVar')
    if highendVar: paramDict[procNum][str(instrument)].append('highendVar')
    if slopeVar: paramDict[procNum][str(instrument)].append('slopeVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(lowstart,i), _wrap(lowend,i), _wrap(highstart,i), _wrap(highend,i), _wrap(slope,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if lowstartVar: line += "%s " % _kbusget(_wrap(lowstartVar,i))
        if lowendVar: line += "%s " % _kbusget(_wrap(lowendVar,i))
        if highstartVar: line += "%s " % _kbusget(_wrap(highstartVar,i))
        if highendVar: line += "%s " % _kbusget(_wrap(highendVar,i))
        if slopeVar: line += "%s " % _kbusget(_wrap(slopeVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fftBufRead(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, bufferlength=1, pointerpos=1, transpo=1, keepformant=0, transpoVar=None, pointerposVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Keeps bufferlength seconds of FFT analysis in memory and plays it back at different rate and different tranposition factor. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
bufferlength = 1
pointerpos = 1 # normalized between 0 and 1
transpo = 1 # ratio (1 -> unchanged)
keepformant = 0 # 0, 1 or 2
transpoVar = None
pointerposVar = None
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    trans = pos = amp = panval = ''
    vars = [transpoVar, pointerposVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, transpo, keepformant = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, transpo, keepformant)
    amplitudeVar, panVar, pointerposVar, transpoVar = _convertVarToList(amplitudeVar, panVar, pointerposVar, transpoVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(transpo), len(keepformant),
              len(bufferlength), len(pointerpos), _len(pointerposVar), _len(amplitudeVar), _len(panVar), _len(transpoVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        orchlines.append("ktime timeinsts\n")
        for i in range(seq):
            orchlines.append("if ktime < %s then\n" % (i, _wrap(bufferlength,i)))
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("ibuf%s, kt%s pvsbuffer fsig%s, %s\n" % (j, j, j, _wrap(bufferlength,i)))
            orchlines.append("endif\n")
            for j in range(_checkChannels()):
                if not pointerposVar:
                    orchlines.append("fsbuf%s pvsbufread %s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(bufferlength,i), j))
                else:
                    orchlines.append("fsbuf%s pvsbufread %s * kbus%s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(pointerposVar,i), _wrap(bufferlength,i), j))
                if not transpoVar:
                    orchlines.append("fbufscale%s pvscale fsbuf%s, %s, %s\n" % (j, j, _wrap(transpo,i), _wrap(keepformant,i)))
                else:
                    orchlines.append("fbufscale%s pvscale fsbuf%s, %s*kpit*kbus%s, %s\n" % (j, j, _wrap(transpo,i), _wrap(transpoVar,i), _wrap(keepformant,i)))
                orchlines.append("a%s%d pvsynth fbufscale%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fftBufRead', int(_whichVars(vars) + offset))
    pval = 13
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if pointerposVar:
            pval, pos = _setxxxVar(pval, 'pos')
        if transpoVar:
            pval, trans = _setxxxVar(pval, 'trans')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("ktime timeinsts\n")
        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
        orchlines.append("if ktime < p11 then\n")
        for j in range(_checkChannels()):
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("ibuf%d, kt%d pvsbuffer fsig%d, p11\n" % (j, j, j))
        orchlines.append("endif\n")
        for j in range(_checkChannels()):
            orchlines.append("fsbuf%d pvsbufread p12%s * p11, ibuf%d\n" % (j, pos, j))
            orchlines.append("fbufscale%d pvscale fsbuf%d, p9%s, p10\n" % (j, j, trans))
            orchlines.append("a%d pvsynth fbufscale%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'transpo', 'keepformant', 'bufferlength', 'pointerpos']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if pointerposVar: paramDict[procNum][str(instrument)].append('pointerposVar')
    if transpoVar: paramDict[procNum][str(instrument)].append('transpoVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(transpo,i), _wrap(keepformant,i), _wrap(bufferlength,i), _wrap(pointerpos,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if pointerposVar: line += "%s " % _kbusget(_wrap(pointerposVar, i))
        if transpoVar: line += "%s " % _kbusget(_wrap(transpoVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fftBufBlur(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, bufferlength=1, pointerpos=1, blur=1, blurVar=None, pointerposVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Keeps bufferlength seconds of FFT analysis in memory and plays it back at different rate and control on blur effects. 

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
bufferlength = 1
pointerpos = 1 # normalized between 0 and 1
blur = 1 # 0 -> 1
blurVar = None
pointerposVar = Non
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    blu = pos = amp = panval = ''
    vars = [blurVar, pointerposVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, blur = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, blur)
    amplitudeVar, panVar, pointerposVar, blurVar = _convertVarToList(amplitudeVar, panVar, pointerposVar, blurVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(blur),
              len(bufferlength), len(pointerpos), _len(pointerposVar), _len(amplitudeVar), _len(panVar), _len(blurVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        orchlines.append("ktime timeinsts\n")
        for i in range(seq):
            orchlines.append("if ktime < %s then\n" % (i, _wrap(bufferlength,i)))
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("ibuf%s, kt%s pvsbuffer fsig%s, %s\n" % (j, j, j, _wrap(bufferlength,i)))
            orchlines.append("endif\n")
            for j in range(_checkChannels()):
                if not pointerposVar:
                    orchlines.append("fsbuf%s pvsbufread %s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(bufferlength,i), j))
                else:
                    orchlines.append("fsbuf%s pvsbufread %s * kbus%s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(pointerposVar,i), _wrap(bufferlength,i), j))
                if not blurVar:
                    orchlines.append("fbufsmooth%s pvsmooth fsbuf%s, %s, 1\n" % (j, j, _wrap(blur,i)))
                else:
                    orchlines.append("fbufsmooth%s pvsmooth fsbuf%s, %s*kbus%s, 1\n" % (j, j, _wrap(blur,i), _wrap(blurVar,i)))
                orchlines.append("a%s%d pvsynth fbufsmooth%s\n" % (j, i, j))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fftBufRead', int(_whichVars(vars) + offset))
    pval = 12
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if pointerposVar:
            pval, pos = _setxxxVar(pval, 'pos')
        if blurVar:
            pval, blu = _setxxxVar(pval, 'blu')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("ktime timeinsts\n")
        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
        orchlines.append("if ktime < p10 then\n")
        for j in range(_checkChannels()):
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("ibuf%d, kt%d pvsbuffer fsig%d, p10\n" % (j, j, j))
        orchlines.append("endif\n")
        for j in range(_checkChannels()):
            orchlines.append("fsbuf%d pvsbufread p11%s * p10, ibuf%d\n" % (j, pos, j))
            orchlines.append("fbufsmooth%d pvsmooth fsbuf%d, p9%s, 1\n" % (j, j, blu))
            orchlines.append("a%d pvsynth fbufsmooth%d\n" % (j, j))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'blur', 'bufferlength', 'pointerpos']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if pointerposVar: paramDict[procNum][str(instrument)].append('pointerposVar')
    if blurVar: paramDict[procNum][str(instrument)].append('blurVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(blur,i), _wrap(bufferlength,i), _wrap(pointerpos,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if pointerposVar: line += "%s " % _kbusget(_wrap(pointerposVar, i))
        if blurVar: line += "%s " % _kbusget(_wrap(blurVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def fftBufAdsyn(input, amplitude=1, duration=None, starttime=0, pan=0.5, fftsize=1024, overlaps=4, windowsize=2048, bufferlength=1, pointerpos=1, transpo=1, numbins=30, firstbin=0, binincr=5, transpoVar=None, pointerposVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Keeps bufferlength seconds of FFT analysis in memory and plays it back at different rate and different tranposition factor. Gives a control on which bin are synthesized.

input = input_sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
fftsize = 1024
overlaps = 4
windowsize = 2048
bufferlength = 1
pointerpos = 1 # normalized between 0 and 1
transpo = 1 # ratio (1 -> unchanged)
numbins = 30
firstbin = 0
binincr = 5
transpoVar = None
pointerposVar = Non
amplitudeVar = None
panVar = None
out = 'dac'"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    trans = pos = amp = panval = ''
    vars = [transpoVar, pointerposVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, transpo, numbins, firstbin, binincr = _convertToList(amplitude, starttime, duration,
                                                                                    pan, input, fftsize, overlaps, windowsize, bufferlength, pointerpos, transpo, numbins, firstbin, binincr)
    amplitudeVar, panVar, pointerposVar, transpoVar = _convertVarToList(amplitudeVar, panVar, pointerposVar, transpoVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(fftsize), len(overlaps), len(windowsize), len(transpo), len(numbins),
              len(firstbin), len(binincr), len(bufferlength), len(pointerpos), _len(pointerposVar), _len(amplitudeVar), _len(panVar), _len(transpoVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        orchlines.append("ktime timeinsts\n")
        for i in range(seq):
            orchlines.append("if ktime < %s then\n" % (i, _wrap(bufferlength,i)))
            for j in range(_checkChannels()):
                orchlines.append("fsig%s pvsanal abus%s%s*%s, %s, %s/%s, %s, 1\n" % (j, j, _wrap(input,i), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i)))
                orchlines.append("ibuf%s, kt%s pvsbuffer fsig%s, %s\n" % (j, j, j, _wrap(bufferlength,i)))
            orchlines.append("endif\n")
            for j in range(_checkChannels()):
                if not pointerposVar:
                    orchlines.append("fsbuf%s pvsbufread %s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(bufferlength,i), j))
                else:
                    orchlines.append("fsbuf%s pvsbufread %s * kbus%s * %s, ibuf%s\n" % (j, _wrap(pointerpos,i), _wrap(pointerposVar,i), _wrap(bufferlength,i), j))
                if not transpoVar:
                    orchlines.append("a%s%d pvsadsyn fsbuf%s, %s, %s, %s, %s\n" % (j, i, j, _wrap(numbins,i), _wrap(transpo,i), _wrap(firstbin,i), _wrap(binincr,i)))
                else:
                    orchlines.append("a%s%d pvsadsyn fsbuf%s, %s, %s*kpit*kbus%s, %s, %s\n" % (j, i, j, _wrap(numbins,i), _wrap(transpo,i), _wrap(transpoVar,i), _wrap(firstbin,i), _wrap(binincr,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d*kbus%s\n" % (j, i, j, i, _wrap(amplitudeVar,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('fftBufAdsyn', int(_whichVars(vars) + offset))
    pval = 15
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if pointerposVar:
            pval, pos = _setxxxVar(pval, 'pos')
        if transpoVar:
            pval, trans = _setxxxVar(pval, 'trans')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("ktime timeinsts\n")
        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
        orchlines.append("if ktime < p11 then\n")
        for j in range(_checkChannels()):
            orchlines.append("fsig%d pvsanal ain%d, p6, p6/p7, p8, 1\n" % (j, j))
            orchlines.append("ibuf%d, kt%d pvsbuffer fsig%d, p11\n" % (j, j, j))
        orchlines.append("endif\n")
        for j in range(_checkChannels()):
            orchlines.append("fsbuf%d pvsbufread p12%s * p11, ibuf%d\n" % (j, pos, j))
            orchlines.append("a%d pvsadsyn fsbuf%d, p10, p9%s, p13, p14\n" % (j, j, trans))
            orchlines.append("a%d = a%d*p5%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'fftsize', 'overlaps', 'windowsize', 'transpo', 'numbins', 'bufferlength', 'pointerpos', 'firstbin', 'binincr']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if pointerposVar: paramDict[procNum][str(instrument)].append('pointerposVar')
    if transpoVar: paramDict[procNum][str(instrument)].append('transpoVar')
    for i in range(seq):
        ainput = _zakget(input[i%len(input)])
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), _wrap(fftsize,i), _wrap(overlaps,i), _wrap(windowsize,i), _wrap(transpo,i), _wrap(numbins,i), _wrap(bufferlength,i), _wrap(pointerpos,i), _wrap(firstbin,i), _wrap(binincr,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if pointerposVar: line += "%s " % _kbusget(_wrap(pointerposVar, i))
        if transpoVar: line += "%s " % _kbusget(_wrap(transpoVar, i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

#####################################################
############### Reverbs instruments #################
def convolveReverb(input, impulse='ORTFFloorR10.wav', amplitude=1, mix=0.1, buffersize=512, duration=None, starttime=0, pan=0.5, amplitudeVar=None, mixVar=None, panVar=None, out='dac'):
    """Apply convolution reverb to the audio signal.

input = sound_input
impulse = path_to_impulse_file
amplitude = 1
mix = 0.1
buffersize = 512
starttime = 0
duration = None
pan = 0.5
amplitudeVar = None
mixVar = None
panVar = None
out = 'dac'

* Can not be used inside MIDI instrument"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = mixWet = mixDry = panval = ''
    vars = [amplitudeVar, mixVar, panVar]
    amplitude, starttime, duration, pan, input, impulse, buffersize, mix = _convertToList(amplitude, starttime, duration,
                                                                                        pan, input, impulse, buffersize, mix)
    amplitudeVar, panVar, mixVar = _convertVarToList(amplitudeVar, panVar, mixVar)
    seq = max(len(input), len(impulse), len(amplitude), len(starttime), len(duration), len(pan), len(mix), _len(amplitudeVar), _len(mixVar), _len(panVar))

    if midiSynthesizer:
        raise Error("You can't use convolution reverb inside a midiInstrument!")

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('convolveReverb', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if mixVar:
            orchlines.append('Smixkbus sprintf "kbus%d"')
            orchlines.append(", p%d\n" % pval)
            orchlines.append("kmix chnget Smixkbus\n")
            pval += 1
            mixWet = '*kmix'
            mixDry = '*(1-kmix)'
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        if _checkChannels() == 1:
            orchlines.append('ain0 zar p4\narev0 pconvolve ain0, p6, p7\n')
            orchlines.append("a0 = ((ain0 * (1 - p8)) + arev0 * p8) * p5%s\n" % amp)
        elif _checkChannels() >= 2:
            orchlines.append("Simpulse1 strget p6\n")
            orchlines.append("ilen strlen Simpulse1\n")
            orchlines.append("Send strsub Simpulse1, ilen-2, -1\n")
            orchlines.append('icomp strcmp Send, ".L"\n')
            orchlines.append("if icomp == 0 then\n")
            orchlines.append("Srmext strsub Simpulse1, 0, ilen-2\n")
            orchlines.append('Simpulse2 strcat Srmext, ".R"\n')
            orchlines.append("ichan2 = 1\n")
            orchlines.append("else\n")
            orchlines.append("Simpulse2 strcpy Simpulse1\n")
            orchlines.append("ichan2 = 2\n")
            orchlines.append("endif\n")
            for i in range(_checkChannels()):
                voice = _checkChannels() - (i + 1)
                orchlines.append("ain%d zar p4-%d\n" % (i, voice))
            for i in range(_checkChannels()):
                if (i % 2) == 0: 
                    chan = '1'
                    impul = 'Simpulse1'
                else: 
                    chan = 'ichan2'
                    impul = 'Simpulse2'
                orchlines.append("arev%d pconvolve ain%d, %s, p7, %s\n" % (i, i, impul, chan))    
            for i in range(_checkChannels()):
                orchlines.append("a%d = ((ain%d * (1 - p8)%s) + arev%d * p8%s) * p5%s\n" % (i, i, mixDry, i, mixWet, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'amplitude', 'impulse', 'buffersize', 'mix']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if mixVar: paramDict[procNum][str(instrument)].append('mixVar')
    for i in range(seq):
        fullname = None
        if os.path.isfile(_wrap(impulse,i)):
            fullname = _wrap(impulse,i)
        elif project_paths:
            for path in project_paths:
                if os.path.isfile(os.path.join(path, _wrap(impulse,i))):
                    fullname = os.path.join(path, _wrap(impulse,i))
                    break
        if not fullname:
            fullname = os.path.join(impulse_path, _wrap(impulse,i))
        if os.path.isfile(fullname): fullname = fullname
        else: fullname = fullname + '.L'
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s "%s" %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(amplitude,i), fullname, str(buffersize[i%len(buffersize)]), str(mix[i%len(mix)]))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if mixVar: line += "%s " % str(_kbusget(mixVar[i%len(mixVar)]))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def reverb(input, amplitude=1, duration=None, starttime=0, revtime=2, highdamp=.5, mix=0.5, pan=0.5, revtimeVar=None, highdampVar=None, mixVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Audio signal is passed through a comb+all-pass reverb.

input = input_sound
amplitude = 1
duration = None
starttime = 0
revtime = 2
highdamp = .5 # 0 -> 1
mix = 0.5
pan = 0.5
revtimeVar = None
highdampVar = None
mixVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
revtime : Duration, in seconds, of the reverberated sound.
highdamp : Amount of high frequencies diffusion, between 0 and 1. If highdamp is set to 0 then all the frequencies decay with the same speed. If highdamp is 1, high frequencies decay faster than lower ones.
mix : Amplitude of reverberated sound vs input sound at the output.
pan : Position value between 0 and 1.
revtimeVar : Name of the control bus multiplying revtime value.
highdampVar : Name of the control bus multiplying highdamp value.
mixVar : Name of the control bus multiplying mix value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    rev = hd = mx = amp = panval = ''
    vars = [revtimeVar, highdampVar, mixVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, revtime, highdamp, mix = _convertToList(amplitude, starttime, duration, pan, input, revtime, highdamp, mix)
    amplitudeVar, panVar, revtimeVar, highdampVar, mixVar = _convertVarToList(amplitudeVar, panVar, revtimeVar, highdampVar, mixVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(revtime), len(highdamp), len(mix), _len(revtimeVar), _len(highdampVar),
              _len(mixVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d nreverb abus%s%s*.25, %s" % (j, i, j, _wrap(input,i), _wrap(revtime,i)))
                if revtimeVar:
                    orchlines.append("*kbus%s" % _wrap(revtimeVar,i))
                orchlines.append(", %s" % _wrap(highdamp,i))
                if highdampVar:
                    orchlines.append("*kbus%s, 0, 32, 8, 8, 9\n" % _wrap(highdampVar,i))
                else:
                    orchlines.append(", 0, 32, 8, 8, 9\n")
                orchlines.append("a%s%d tonex a%s%d, 5000, 3\n" % (j, i, j, i))
                if not mixVar:
                    orchlines.append("a%s%d = (a%s%d * sqrt(%s)) + (abus%s%s * sqrt(1 - %s))\n" % (j, i, j, i, _wrap(mix,i), j, _wrap(input,i), _wrap(mix,i))) 
                else:
                    orchlines.append("a%s%d = (a%s%d * sqrt(%s * kbus%s)) + (abus%s%s * sqrt(1 - (%s * kbus%s)))\n" % (j, i, j, i, _wrap(mix,i), _wrap(mixVar,i), j, _wrap(input,i), _wrap(mix,i), _wrap(mixVar,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('reverb', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if revtimeVar:
            pval, rev = _setxxxVar(pval, 'rev')
        if highdampVar:
            pval, hd = _setxxxVar(pval, 'hd')
        if mixVar:
            pval, mx = _setxxxVar(pval, 'mx')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p7-%d\na%d nreverb ain%d*.25, p4%s, p5%s, 0, 32, 8, 8, 9\n" % (j, voice, j, j, rev, hd))
            orchlines.append("a%d tonex a%d, 5000, 3\n" % (j, j))
            orchlines.append("a%d = (a%d * sqrt(p8%s)) + (ain%d * sqrt(1 - (p8%s)))\n" % (j, j, mx, j, mx))
            orchlines.append("a%d = a%d * p6%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'revtime', 'highdamp', 'amplitude', 'input', 'mix']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if revtimeVar: paramDict[procNum][str(instrument)].append('revtimeVar')
    if highdampVar: paramDict[procNum][str(instrument)].append('highdampVar')
    if mixVar: paramDict[procNum][str(instrument)].append('mixVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(revtime,i), _wrap(highdamp,i), _wrap(amplitude,i), str(ainput), _wrap(mix,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if revtimeVar: line += "%s " % _kbusget(_wrap(revtimeVar,i))
        if highdampVar: line += "%s " % _kbusget(_wrap(highdampVar,i))
        if mixVar: line += "%s " % _kbusget(_wrap(mixVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def waveguideReverb(input, amplitude=1, duration=None, starttime=0, feedback=.7, cutoff=10000, mix=0.5, randomize=1, pan=0.5, feedbackVar=None, cutoffVar=None, mixVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Audio signal is passed through a 8 delay line feedback network reverb.

input = input_sound
amplitude = 1
duration = None
starttime = 0
feedback = .7 # 0 -> 1
cutoff = 10000 # hertz
mix = 0.5
randomize = 1 # 0 -> 10
pan = 0.5
feedbackVar = None
cutoffVar = None
mixVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
feedback : Feedback level, in the range 0 to 1.
cutoff : Cutoff frequency of simple first order lowpass filters in the feedback loop of delay lines, in Hz.
mix : Amplitude of reverberated sound vs input sound at the output.
randomize : Depth of random variation added to delay times, in the range 0 to 10.
pan : Position value between 0 and 1.
feedbackVar : Name of the control bus multiplying feedback value.
cutoffVar : Name of the control bus multiplying cutoff value.
mixVar : Name of the control bus multiplying mix value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    feed = cut = mx = amp = panval = ''
    vars = [feedbackVar, cutoffVar, mixVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, feedback, cutoff, mix, randomize = _convertToList(amplitude, starttime, duration, pan, input, feedback, cutoff, mix, randomize)
    amplitudeVar, panVar, feedbackVar, cutoffVar, mixVar = _convertVarToList(amplitudeVar, panVar, feedbackVar, cutoffVar, mixVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(feedback), len(cutoff), len(mix), len(randomize), _len(feedbackVar), _len(cutoffVar),
              _len(mixVar), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(0, _checkChannels(), 2):
                if j == _checkChannels() - 1:
                    orchlines.append("arev%d%d, arev%d%d reverbsc abus%d%s, abus%d%s, %s" % (j, i, (j+1), i, j, _wrap(input,i), j, _wrap(input,i), _wrap(feedback,i)))
                    if feedbackVar:
                        orchlines.append("*kbus%s" % _wrap(feedbackVar,i))
                    orchlines.append(", %s" % _wrap(cutoff,i))
                    if cutoffVar:
                        orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                    orchlines.append(", sr, %s\n" % _wrap(randomize,i))
                    orchlines.append("a%d%d = (arev%d%d + arev%d%d) * .707\n" % (j, i, j, i, (j+1), i))
                    if not mixVar:
                        orchlines.append("a%d%d = (a%d%d * sqrt(%s)) + (abus%d%s * sqrt(1 - %s))\n" % (j, i, j, i, _wrap(mix,i), j, _wrap(input,i), _wrap(mix,i))) 
                    else:
                        orchlines.append("a%d%d = (a%d%d * sqrt(%s * kbus%s)) + (abus%d%s * sqrt(1 - (%s * kbus%s)))\n" % (j, i, j, i, _wrap(mix,i), _wrap(mixVar,i), j, _wrap(input,i), _wrap(mix,i), _wrap(mixVar,i)))
                    if amplitudeVar:
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                    else:
                        orchlines.append("a%d%d = a%d%d * %s\n" % (j, i, j, i, _wrap(amplitude,i))) 
                else:
                    orchlines.append("arev%d%d, arev%d%d reverbsc abus%d%s, abus%d%s, %s" % (j, i, (j+1), i, j, _wrap(input,i), (j+1), _wrap(input,i), _wrap(feedback,i)))
                    if feedbackVar:
                        orchlines.append("*kbus%s" % _wrap(feedbackVar,i))
                    orchlines.append(", %s" % _wrap(cutoff,i))
                    if cutoffVar:
                        orchlines.append("*kbus%s" % _wrap(cutoffVar,i))
                    orchlines.append(", sr, %s\n" % _wrap(randomize,i))
                    if not mixVar:
                        orchlines.append("a%d%d = (arev%d%d * sqrt(%s)) + (abus%d%s * sqrt(1 - %s))\n" % (j, i, j, i, _wrap(mix,i), j, _wrap(input,i), _wrap(mix,i))) 
                        orchlines.append("a%d%d = (arev%d%d * sqrt(%s)) + (abus%d%s * sqrt(1 - %s))\n" % ((j+1), i, (j+1), i, _wrap(mix,i), (j+1), _wrap(input,i), _wrap(mix,i))) 
                    else:
                        orchlines.append("a%d%d = (arev%d%d * sqrt(%s * kbus%s)) + (abus%d%s * sqrt(1 - (%s * kbus%s)))\n" % (j, i, j, i, _wrap(mix,i), _wrap(mixVar,i), j, _wrap(input,i), _wrap(mix,i), _wrap(mixVar,i)))
                        orchlines.append("a%d%d = (arev%d%d * sqrt(%s * kbus%s)) + (abus%d%s * sqrt(1 - (%s * kbus%s)))\n" % ((j+1), i, (j+1), i, _wrap(mix,i), _wrap(mixVar,i), (j+1), _wrap(input,i), _wrap(mix,i), _wrap(mixVar,i)))
                    if amplitudeVar:
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % ((j+1), i, (j+1), i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                    else:
                        orchlines.append("a%d%d = a%d%d * %s\n" % (j, i, j, i, _wrap(amplitude,i))) 
                        orchlines.append("a%d%d = a%d%d * %s\n" % ((j+1), i, (j+1), i, _wrap(amplitude,i))) 
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('waveguideReverb', int(_whichVars(vars) + offset))
    pval = 10
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if feedbackVar:
            pval, feed = _setxxxVar(pval, 'feed')
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if mixVar:
            pval, mx = _setxxxVar(pval, 'mx')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(0, _checkChannels(), 2):
            voice = _checkChannels() - (j+1)
            if j == _checkChannels() - 1:
                orchlines.append("ain%d zar p7-%d\n" % (j, voice))
                orchlines.append("arev%d, arev%d reverbsc ain%d, ain%d, p4%s, p5%s, sr, p9\n" % (j, (j+1), j, j, feed, cut))
                orchlines.append("a%d = (arev%d + arev%d) * .707\n" % (j, j, (j+1)))
                orchlines.append("a%d = (a%d * sqrt(p8%s)) + (ain%d * sqrt(1 - (p8%s)))\n" % (j, j, mx, j, mx))
                orchlines.append("a%d = a%d * p6%s\n" % (j, j, amp))
            else:    
                orchlines.append("ain%d zar p7-%d\nain%d zar p7-%d\n" % (j, voice, (j+1), (voice-1)))
                orchlines.append("arev%d, arev%d reverbsc ain%d, ain%d, p4%s, p5%s, sr, p9\n" % (j, (j+1), j, (j+1), feed, cut))
                orchlines.append("a%d = (arev%d * sqrt(p8%s)) + (ain%d * sqrt(1 - (p8%s)))\n" % (j, j, mx, j, mx))
                orchlines.append("a%d = (arev%d * sqrt(p8%s)) + (ain%d * sqrt(1 - (p8%s)))\n" % ((j+1), (j+1), mx, (j+1), mx))
                orchlines.append("a%d = a%d * p6%s\n" % (j, j, amp))
                orchlines.append("a%d = a%d * p6%s\n" % ((j+1), (j+1), amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'feedback', 'cutoff', 'amplitude', 'input', 'mix', 'randomize']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if feedbackVar: paramDict[procNum][str(instrument)].append('feedbackVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    if mixVar: paramDict[procNum][str(instrument)].append('mixVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(feedback,i), _wrap(cutoff,i), _wrap(amplitude,i), str(ainput), _wrap(mix,i), _wrap(randomize,i))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if feedbackVar: line += "%s " % _kbusget(_wrap(feedbackVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if mixVar: line += "%s " % _kbusget(_wrap(mixVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def infiniteReverb(input, trigbus, clearbus, amplitude=1, duration=None, starttime=0, cutoff=10000, pan=0.5, cutoffVar=None, amplitudeVar=None, panVar=None, out='dac'):
    """Each time a trigger is detected on trigbus, a little snapshot of sound in input is infinitely reverberated. A trigger on clearbus clears reverb memory.

input = input_sound
trigbus = trigger_bus
clearbus = reset_reverb_bus
amplitude = 1
duration = None
starttime = 0
cutoff = 10000 # hertz
pan = 0.5
cutoffVar = None
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
trigbus : Name of the controller bus waiting for a trigger signal.
clearbus : Name of the controller bus waiting for a trigger signal to clear reverb memory.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
cutoff : Cutoff frequency of simple first order lowpass filters in the feedback loop of delay lines, in Hz.
pan : Position value between 0 and 1.
cutoffVar : Name of the control bus multiplying cutoff value.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    cut = amp = panval = ''
    vars = [cutoffVar, amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input, cutoff, trigbus, clearbus = _convertToList(amplitude, starttime, duration, pan, input, cutoff, trigbus, clearbus)
    amplitudeVar, panVar, cutoffVar = _convertVarToList(amplitudeVar, panVar, cutoffVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), len(trigbus), len(cutoff), len(clearbus), _len(cutoffVar),
              _len(amplitudeVar), _len(panVar))

    if 'trigEnv' not in UDO:
        UDO.append('trigEnv')
    if 'trigClearRev' not in UDO:
        UDO.append('trigClearRev')
        
    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            orchlines.append("ktrig%d trigEnv kbus%s, .25, 6\n" % (i, _wrap(trigbus,i)))
            orchlines.append("kclear%d trigClearRev kbus%s\n" % (i, _wrap(clearbus,i)))
            for j in range(0, _checkChannels(), 2):
                if j == _checkChannels() - 1:
                    orchlines.append("arevin%d%d = abus%d%s * ktrig%d\n" % (j, i, j, _wrap(input,i), i))
                    orchlines.append("arev%d%d, arev%d%d reverbsc arevin%d%d, arevin%d%d, 1*kclear%d, sr/2.1, sr, 1\n" % (j, i, (j+1), i, j, i, j, i, i))
                    orchlines.append("a%d%d = (arev%d%d + arev%d%d) * .707\n" % (j, i, j, i, (j+1), i))
                    orchlines.append("a%d%d butterlp a%d%d, %s" % (j, i, j, i, _wrap(cutoff,i)))
                    if cutoffVar:
                        orchlines.append("*kbus%s\n" % _wrap(cutoffVar,i))
                    else:
                        orchlines.append('\n')
                    if amplitudeVar:
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                    else:
                        orchlines.append("a%d%d = a%d%d * %s\n" % (j, i, j, i, _wrap(amplitude,i))) 
                else:
                    orchlines.append("arevin%d%d = abus%d%s * ktrig%d\n" % (j, i, j, _wrap(input,i), i))
                    orchlines.append("arevin%d%d = abus%d%s * ktrig%d\n" % ((j+1), i, (j+1), _wrap(input,i), i))
                    orchlines.append("arev%d%d, arev%d%d reverbsc arevin%d%s, arevin%d%s, 1*kclear%d, sr/2.1, sr, 1\n" % (j, i, (j+1), i, j, i, (j+1), i, i))
                    if not cutoffVar:
                        orchlines.append("a%d%d butterlp arev%d%d, %s" % (j, i, j, i, _wrap(cutoff,i)))
                        orchlines.append("a%d%d butterlp arev%d%d, %s" % ((j+1), i, (j+1), i, _wrap(cutoff,i)))
                    else:    
                        orchlines.append("a%d%d butterlp arev%d%d, %s*kbus%s" % (j, i, j, i, _wrap(cutoff,i), _wrap(cutoffVar,i)))
                        orchlines.append("a%d%d butterlp arev%d%d, %s*kbus%s" % ((j+1), i, (j+1), i, _wrap(cutoff,i), _wrap(cutoffVar,i)))
                    if amplitudeVar:
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                        orchlines.append("a%d%d = a%d%d * %s * kbus%s\n" % ((j+1), i, (j+1), i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                    else:
                        orchlines.append("a%d%d = a%d%d * %s\n" % (j, i, j, i, _wrap(amplitude,i))) 
                        orchlines.append("a%d%d = a%d%d * %s\n" % ((j+1), i, (j+1), i, _wrap(amplitude,i))) 
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('infiniteReverb', int(_whichVars(vars) + offset))
    pval = 9
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if cutoffVar:
            pval, cut = _setxxxVar(pval, 'cut')
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        orchlines.append("ktrig init -1\n")  
        orchlines.append('Strig%dkbus ' % instrument)
        orchlines.append('sprintf "kbus%d"')
        orchlines.append(", p4\n")
        orchlines.append("ktrig chnget Strig%dkbus\n" % instrument)
        orchlines.append("ktrigEnv trigEnv ktrig, .25, 6\n")
        orchlines.append("ktrigCl init -1\n")  
        orchlines.append('StrigCl%dkbus ' % instrument)
        orchlines.append('sprintf "kbus%d"')
        orchlines.append(", p8\n")
        orchlines.append("ktrigCl chnget StrigCl%dkbus\n" % instrument)
        orchlines.append("ktrigClear trigClearRev ktrigCl\n")
        
        for j in range(0, _checkChannels(), 2):
            voice = _checkChannels() - (j+1)
            if j == _checkChannels() - 1:
                orchlines.append("ain%d zar p7-%d\n" % (j, voice))
                orchlines.append("ainrev%d = ain%d * ktrigEnv\n" % (j, j))
                orchlines.append("arev%d, arev%d reverbsc ainrev%d, ainrev%d, 1*ktrigClear, sr/2.1, sr, 1\n" % (j, (j+1), j, j))
                orchlines.append("a%d = (arev%d + arev%d) * .707\n" % (j, j, (j+1)))
                orchlines.append("a%d butterlp a%d, p5%s\n" % (j, j, cut))
                orchlines.append("a%d = a%d * p6%s\n" % (j, j, amp))
            else:    
                orchlines.append("ain%d zar p7-%d\nain%d zar p7-%d\n" % (j, voice, (j+1), (voice-1)))
                orchlines.append("ainrev%d = ain%d * ktrigEnv\n" % (j, j))
                orchlines.append("ainrev%d = ain%d * ktrigEnv\n" % ((j+1), (j+1)))
                orchlines.append("arev%d, arev%d reverbsc ainrev%d, ainrev%d, 1*ktrigClear, sr/2.1, sr, 1\n" % (j, (j+1), j, (j+1)))
                orchlines.append("a%d butterlp arev%d, p5%s\n" % (j, j, cut))
                orchlines.append("a%d butterlp arev%d, p5%s\n" % ((j+1), (j+1), cut))
                orchlines.append("a%d = a%d * p6%s\n" % (j, j, amp))
                orchlines.append("a%d = a%d * p6%s\n" % ((j+1), (j+1), amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'trigbus', 'cutoff', 'amplitude', 'input', 'clearbus']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if cutoffVar: paramDict[procNum][str(instrument)].append('cutoffVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _kbusget(_wrap(trigbus,i)), _wrap(cutoff,i), _wrap(amplitude,i), str(ainput), _kbusget(_wrap(clearbus,i)))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if cutoffVar: line += "%s " % _kbusget(_wrap(cutoffVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


#####################################################
############### Panning functions ###################
def spat1to4(input, starttime=0, duration=None, xpos=.5, ypos=.5, xposVar=None, yposVar=None, out='dac'):
    """Takes a mono input and distributes it in an arbitrary four channels space.
    
input = mono_input
starttime = 0
duration = None
xpos = 0.5 # 0 -> 1
ypos = 0.5 # 0 -> 1
xposVar = None
yposVar = None
out = 'dac'
"""
    usednchnls.append(4)
    if not duration: duration = GDUR
    outpval = 0
    xp = yp = ''
    vars = [xposVar, yposVar]
    starttime, duration, xpos, ypos, input = _convertToList(starttime, duration, xpos, ypos, input)
    xposVar, yposVar = _convertVarToList(xposVar, yposVar)
    seq = max(len(input), len(xpos), len(ypos), len(starttime), len(duration), _len(xposVar), _len(yposVar))

    if midiSynthesizer:                
        _initAudioBusMidi(out)
        for i in range(seq):
            if not xposVar and not yposVar:
                orchlines.append("a0%d, a1%d, a2%d, a3%d pan abus%s, %s, %s, 7, 1, 0\n" % (i, i, i, i, _wrap(input,i), _wrap(xpos,i), _wrap(ypos,i)))
            elif xposVar and not yposVar:
                orchlines.append("a0%d, a1%d, a2%d, a3%d pan abus%s, kbus%s, %s, 7, 1, 0\n" % (i, i, i, i, _wrap(input,i), _wrap(xposVar,i), _wrap(ypos,i)))
            elif not xposVar and yposVar:
                orchlines.append("a0%d, a1%d, a2%d, a3%d pan abus%s, %s, kbus%s, 7, 1, 0\n" % (i, i, i, i, _wrap(input,i), _wrap(xpos,i), _wrap(yposVar,i))) 
            else:
                orchlines.append("a0%d, a1%d, a2%d, a3%d pan abus%s, kbus%s, kbus%s, 7, 1, 0\n" % (i, i, i, i, _wrap(input,i), _wrap(xposVar,i), _wrap(yposVar,i)))  
            if out != 'dac':
                for j in range(4):
                    orchlines.append("abus%s%s = a%s%d + abus%s%s\n" % (j, str(out), j, i, j, str(out)))
                if str(out) not in midiInstBusAudio:
                    midiInstBusAudio.append(str(out))
            else:
                for j in range(4):
                    orchlines.append("gamidiout%s%d = a%s%d + gamidiout%s%s\n" % (j, i, j, i, j, i))
                if i not in midiInstOutAudio:
                    midiInstOutAudio.append(i)
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('spat1to4', int(_whichVars(vars) + offset))
    pval = 7
    if out != 'dac':
        out = _zakset(out, 4)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if xposVar:
            pval, xp = _setxxxVar(pval, xp)
        if yposVar:
            pval, yp = _setxxxVar(pval, yp)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)
                    
        orchlines.append("ain zar p4\n")        
        if not xposVar and not yposVar:
            orchlines.append("aout0, aout1, aout2, aout3 pan ain, p5, p6, 7, 1, 0\n")
        elif xposVar and not yposVar:
            orchlines.append("idump = p5\n")
            orchlines.append("aout0, aout1, aout2, aout3 pan ain, %s, p6, 7, 1, 0\n" % xp)
        elif not xposVar and yposVar:
            orchlines.append("idump = p6\n")
            orchlines.append("aout0, aout1, aout2, aout3 pan ain, p5, %s, 7, 1, 0\n" % yp)   
        else:
            orchlines.append("idump = p5\nidump2 = p6\n")
            orchlines.append("aout0, aout1, aout2, aout3 pan ain, %s, %s, 7, 1, 0\n" % (xp, yp)) 
        if out == 'dac':
            for j in range(4):
                orchlines.append("gaout%s = aout%s + gaout%s\n" % (j, j, j))
        else:
            for j in range(4):
                offset = 3 - j
                orchlines.append("zawm aout%s, p%d-%d\n" % (j, outpval, offset))
        orchlines.append("endin\n\n")
                    
    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'xpos', 'ypos']
    if xposVar: paramDict[procNum][str(instrument)].append('xposVar')
    if yposVar: paramDict[procNum][str(instrument)].append('yposVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(xpos,i), _wrap(ypos,i))
        if xposVar: line += "%s " % str(_kbusget(_wrap(xposVar,i)))
        if yposVar: line += "%s " % str(_kbusget(_wrap(yposVar,i)))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def pan1to2(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a mono input and distributes it on two channels.
    
input = mono_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=1, numoutputs=2, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def pan1to4(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a mono input and distributes it on a four channels circle.
    
input = mono_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=1, numoutputs=4, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def pan1to8(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a mono input and distributes it on a eight channels circle.
    
input = mono_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=1, numoutputs=8, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def pan2to4(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a stereo input and distributes it on a four channels circle.
    
input = stereo_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=2, numoutputs=4, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def pan2to8(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a stereo input and distributes it on a eight channels circle.
    
input = stereo_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=2, numoutputs=8, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def pan4to8(input, starttime=0, duration=None, pan=.5, panVar=None, out='dac'):
    """Takes a quad input and distributes it on a eight channels circle.
    
input = quad_input
starttime = 0
duration = None
pan = 0.5 # 0 -> 1
panVar = None
out = 'dac'
"""
    panner(input=input, starttime=starttime, duration=duration, numinputs=4, numoutputs=8, pan=pan, offset=0, spread=0, panVar=panVar, spreadVar=None, out=out)

def panner(input, starttime=0, duration=None, numinputs=1, numoutputs=2, pan=.5, offset=0, spread=.5, panVar=None, spreadVar=None, out='dac'):
    """Takes an input with an arbitrary number of channels and distributes it on an arbitrary number of channels.
    
input = audio_input
starttime = 0
duration = None
numinputs = 1 # can't be a list 
numoutputs = 2 # can't be a list
pan = 0.5 # 0 -> 1
offset = 0 # can't be a list
spread = 0.5 # 0 -> 1
panVar = None # override pan
spreadVar = None # override spread
out = 'dac'
"""
    usednchnls.append(numoutputs)
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    panval = sprd = ''
    vars = [panVar, spreadVar]
    starttime, duration, pan, input, spread = _convertToList(starttime, duration, pan, input, spread)
    panVar, spreadVar = _convertVarToList(panVar, spreadVar)
    seq = max(len(input), len(pan), len(starttime), len(duration), len(spread), _len(panVar), _len(spreadVar))

    name = 'panner%d' % numoutputs
    
    if midiSynthesizer:                
        _initAudioBusMidi(out)
        for i in range(seq):
            if spreadVar:
                sprd = 'kbus%s' % _wrap(spreadVar,i)
            else:
                sprd = _wrap(spread,i)
            _outPanMidiSig(i, out, pan, panVar, numinputs, numoutputs, sprd, offset)
        return
                
    if out == 'dac': instoffset = 0
    else: instoffset = int(math.pow(2, len(vars)))
    instrument = _checkInst(name, int(_whichVars(vars) + instoffset))
    pval = 6
    if out != 'dac':
        out = _zakset(out, 8)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if numoutputs > 1:
            ipanpval, pval = _setpan(pval)
        if panVar:
            pval, panval = _setpanVar(pval)
        if spreadVar:
            pval, sprd = _setspreadVar(pval)
        else:
            sprd = 'p5'
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)
              
        for i in range(numinputs):
            voice = numinputs - (i+1)
            orchlines.append('a%d zar p4-%d\n' % (i, voice))
        _outPanSig(out, outpval, ipanpval, panval, numinputs, numoutputs, sprd, offset)

                    
    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'spread']
    if numoutputs > 1: paramDict[procNum][str(instrument)].append('pan')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    if spreadVar: paramDict[procNum][str(instrument)].append('spreadVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(spread,i))
        if numoutputs > 1: line += "%s " % _wrap(pan,i)
        if panVar: line += "%s " % str(_kbusget(_wrap(panVar,i)))
        if spreadVar: line += "%s " % str(_kbusget(_wrap(spreadVar,i)))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)


#####################################################
########### Writing CSD file and output #############
def startCsound(duration=None, file=None, channels=None, amplitude=1, nosound=False, withevents=True):
    """Compiles a .csd file and starts csound with it. If a string is given as a second argument, it writes a file on disk instead of sending sound to speakers.

duration = None
file = None
channels = None # force the number of output channels.
amplitude = 1
nosound = False

if channels == None, channels are given by highest setChannels or panning functions.

return Ounk process number of the script. Can be used to send events to Csound from the interpreter.

--- PARAMETERS ---

duration : Duration of the function performance in seconds. Uses global duration if 'None'.
file : If a string is given, Csound will write a file on disk instead of sending sound to speakers. Extension (.aif or .wav), defined by 'audioFormat', will be added to filename. Sounds will be saved in prefered snds folder.
channels : Forces the number of Csound audio output channels.
amplitude : Adjust the overall amplitude of the performance.
nosound : If this parameter is True, no sound will be send to dac (digital to analog converter).
"""
    global midi, outnchnls
    outnchnls = channels
    if outnchnls: 
        activeChannels = outnchnls
    else:
        if usednchnls: activeChannels = max(usednchnls)
        else: activeChannels = nchnls    
    if not duration: duration = GDUR
    csnchnls = _output(duration, activeChannels, amplitude, nosound, withevents)
    path = temp_path
    if midifile:
        midi = midifile
    if not ladspaPlugin:
        csd = open(os.path.join(temp_path, "temp%d.csd" % procNum), "w")
        csd.write("<CsoundSynthesizer>\n\n")
        csd.write("<CsOptions>\n")
        if file == None:
            if driver == 'jack': 
                client = '-+jack_client=csound%d' % procNum
                odev = '-odac:alsa_pcm:playback_'
            else: 
                client = ''
                odev = '-odevaudio'
            if auFormat == 'wav' or auFormat == 'wave':
                csd.write("-+rtaudio=%s %s %s%s %s%s -W -Lstdin %s -d %s %s -m0 -b%d -B%d\n" % (driver, client, inadc, audiodevin, odev, audiodevout, midi, display, format, softBuf, hardBuf))
            elif auFormat == 'aif' or auFormat == 'aiff':
                csd.write("-+rtaudio=%s %s %s%s %s%s -A -Lstdin %s -d %s %s -m0 -b%d -B%d\n" % (driver, client, inadc, audiodevin, odev, audiodevout, midi, display, format, softBuf, hardBuf))
            else:
                return "Bad audio file format! ('wav' or 'aif')"
        else:
            if auFormat == 'wav' or auFormat == 'wave':
                outfile = os.path.join(sound_path, str(file)) + ".wav"
                if os.path.isfile(outfile):
                    listdir = os.listdir(sound_path)
                    samefile = [f for f in listdir if str(file) + "-" in f]
                    fileinc = len(samefile)
                    outfile = os.path.join(sound_path, str(file) + "-%d.wav" % fileinc)
                csd.write("-+rtaudio=%s -o%s -m0 %s -W -Lstdin -d %s -b%d -B%d\n" % (driver, outfile, midi, format, softBuf, hardBuf))
            elif auFormat == 'aif' or auFormat == 'aiff':
                outfile = os.path.join(sound_path, str(file)) + ".aif"
                if os.path.isfile(outfile):
                    listdir = os.listdir(sound_path)
                    samefile = [f for f in listdir if str(file) + "-" in f]
                    fileinc = len(samefile)
                    outfile = os.path.join(sound_path, str(file) + "-%d.aif" % fileinc)
                csd.write("-+rtaudio=%s -o%s -m0 %s -A -Lstdin -d %s -b%d -B%d\n" % (driver, outfile, midi, format, softBuf, hardBuf))
            else:
                return "Bad audio file format! ('wav' or 'aif')"
        csd.write("</CsOptions>\n\n")
    else:
        csd = open(os.path.join(sound_path, "%s.csd" % ladspaName), "w")
        csd.write("<csLADSPA>\n")
        csd.write("Name=%s\n" % ladspaName)
        csd.write("Maker=%s\n" % os.getenv("USER", "Ounk"))
        csd.write("UniqueID=%d\n" % random.randint(2000,20000))
        csd.write("Copyright=None\n")
        for key in ladspaDict.keys():
            csd.write("ControlPort=%s|kbus%s\n" % (key, str(_kbusget(ladspaDict[key][0]))))
            csd.write("Range=%s|%s" % (ladspaDict[key][1], ladspaDict[key][2]))
            if ladspaDict[key][3] == True:
                csd.write(" &log\n")
            else:
                csd.write("\n")
        csd.write("</csLADSPA>\n\n")
        csd.write("<CsoundSynthesizer>\n\n")
        csd.write("<CsOptions>\n-d\n</CsOptions>\n\n")
    csd.write("<CsInstruments>\n\n")
    csd.write("sr=%d\nkr=%d\nnchnls=%d\n\n" % (sr, kr, csnchnls))

    if stringSetDict:
        for setName in stringSetDict.keys():
            csd.write('strset %s, "%s"\n' % (stringSetDict[setName], setName))
        csd.write('\n')
        
    if insideSoundfont:
        for line in soundfontlines:
            csd.write(line)
    if midiSynthesizerChannel:
        for i in midiSynthesizerChannel:
            csd.write("massign %d, %d\nturnon %d\n\n" % (i, i, i))
        for j in range(activeChannels):
            for i in midiInstOutAudio:
                csd.write("gamidiout%d%d init 0\n" % (j, i))

    if kratebus:
        for bus in kratebus.values():
            csd.write('chn_k "kbus%s", 3\n' % bus)
    csd.write("\n")        
    for j in range(activeChannels):  
        csd.write("gaout%d init 0\n" % j)
    csd.write("\n")
    if len(zakindex) > 0:
    	csd.write("zakinit %d, 1\n\n" % max(zakindex.values()))

    if oscPort:
        for port in oscPort:
            csd.write("gi%s OSCinit %s\n\n" % (port, port))

    for udo in UDO:
        csd.write(udoDict[udo])
    if pannerlines:
        for line in pannerlines:
            csd.write(line)

    for line in orchlines:
        csd.write(line.encode('utf-8'))
    csd.write("\n</CsInstruments>\n\n<CsScore>\n\n")
    if duration < 0:
        csd.write("f0 60000\n") # start csound for a long time
    csd.write("f1 0 8192 10 1\n") # sine wave
    csd.write("f2 0 8192 10 1 0 .33 0 .2 0 .143 0 .111\n") # square wave
    csd.write("f3 0 8192 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n") # sawtooth wave
    csd.write("f4 0 8192 11 1\n") # cosine wave
    csd.write("f5 0 8192 9 0.5 1 0\n") # half of a sine wave
    csd.write("f6 0 8192 20 2\n") # hanning window
    csd.write("f7 0 8193 9 0.25 1 0\n") # quad of a sine wave
    # nreverb tables
    csd.write("f8 0 64 -2 -1009 -1103 -1123 -1281 -1289 -1307 -1361 -1409 -1429 -1543 -1583 -1601 -1613 -1709 -1801 -1949 -2003 -2111 -2203 -2341 -2411 -2591 -2609 -2749 -2801 -2903 -3001 -3109 -3203 -3301 -3407 -3539 0.82 0.81 0.8 0.79 0.78 0.77 0.76 0.75 0.74 0.73 0.72 0.71 0.7 0.69 0.68 0.67 0.66 0.65 0.64 0.63 0.62 0.61 0.6 0.59 0.58 0.57 0.56 0.55 0.54 0.53 0.52 0.51\n")
    csd.write("f9 0 16 -2 -179 -223 -233 -311 -347 -409 -433 -509 0.76 0.74 0.72 0.7 0.68 0.64 0.62 0.6\n")
    csd.write("f10 0 8192 10 1 0 0 .3 0 .2 0 0 .1\n") # default complex wave
    csd.write("f11 0 8192 7 1 8192 1\n") # rectangular envelope
    if voiceTables:
        csd.write('\n#include "' + os.path.join(resources_path, 'voiceSynth', 'tables.txt') + '"\n\n')
    for line in scorelines:
        csd.write(line.encode('utf-8'))
    csd.write("e\n\n</CsScore>\n\n</CsoundSynthesizer>")
    csd.close()

    if not ladspaPlugin:
        return _csoundstuff(0)
    else:
        clear()

def ounkInit(num=1):
    """Reinitializes ounk global variables. When ounk is used as a standard Python library (outside his own GUI), this function must be called after each call of stopCsound() or to erase all variables from preceding signal processing.

num = 1 # Ounk process number"""
    processNumber(num)
        
def processNumber(num):
    global procNum
    procNum = num
    pythonlines[procNum] = {}
    instrumentDict[procNum] = {}
    paramDict[procNum] = {}
    patternDict[procNum] = []
    guiDict[procNum] = []
    
def stopCsound(num=None):
    """Stops the current csound instance and running processes."""
    if num == None:
        for key in processDict.keys():
            killThreads(key)
        if systemPlatform == 'darwin':
            for key in processDict.keys():
                os.system("kill %d" % processDict[key])
        elif systemPlatform == 'win32':
            os.system('taskkill /F /IM csound.exe')
        else:
            os.system("killall csound")
        for key in processDict.keys():
            del processDict[key]
            del pythonlines[key]
            del paramDict[key]
    elif processDict.has_key(num):
        killThreads(num)
        if systemPlatform == 'darwin':
            os.system("kill %d" % processDict[num])
        elif systemPlatform == 'win32':
            os.system('taskkill /F /IM csound.exe')
        else:
            os.system("killall csound")        
        del processDict[num]
        del pythonlines[num]
        del paramDict[num]

    else:
        for f in guiDict[num]:
            f.Destroy()
        del guiDict[num]

def getPid(num=None):
    """Returns the csound process id.
    """
    if num and processDict.has_key(num):
        return processDict[num]
    elif not num and processDict.keys() != []:
        return processDict
    else:        
        print "There is no csound process in run"
        return None
        
def checkCsound(num=None):
    if _csoundstuff(2, num=num) and processDict.has_key(num):
        return True
    else:
        return False

def playCSD(file):
    _csoundstuff(0, None, None, file)
    
def _csoundstuff(met, line=None, num=None, file=None):
    global stdin, cspid
    if met == 0:
        log = '--logfile=' + os.path.join(temp_path, 'csoundlog.txt')
        if not file:
            csdfile = os.path.join(temp_path, 'temp%d.csd' % procNum)
        else:
            csdfile = file
        if systemPlatform == 'darwin' and '/Ounk.app' in os.getcwd():
            cspipe = Popen('nice -n -10 /usr/local/bin/csound ' + log + ' ' + csdfile, shell=True, stdin=PIPE)
        elif systemPlatform == 'darwin':
            cspipe = Popen('nice -n -20 /usr/local/bin/csound ' + log + ' ' + csdfile, shell=True, stdin=PIPE)
        elif systemPlatform == 'win32':
            cspipe = Popen('start /B /REALTIME /WAIT csound "' + log + '" "' + csdfile + '"', shell=True) #, creationflags=8)
        else:
            try:
                os.nice(-10)
                nicy = -10
            except:
                nicy = 0
            if driver == 'jack': 
                command = 'csound ' + log + ' '
            else:
                command = 'csound ' + log + ' '
            cspipe = Popen('nice -n %s ' % nicy + command + csdfile, shell=True, stdin=PIPE)         
        stdin, stdout, cspid = cspipe.stdin, cspipe.stdout, cspipe.pid
        cspipeDict[procNum] = [cspipe, stdin, stdout]
        processDict[procNum] = cspid
        clear()
        return procNum
    elif met == 1:
        try:
            cspipeDict[num][1].write(line)
        except:
            pass
    else:
        if cspipeDict.has_key(num):
            if cspipeDict[num][0] != None:
                returncode = cspipeDict[num][0].poll()
                if returncode < 0:
                    return True
                else:
                    return False
            
def killThreads(num):
    if patternDict.has_key(num):
        for pat in patternDict[num]:
            pat.stop() 
        del patternDict[num]
    if guiDict.has_key(num):    
        for f in guiDict[num]:
            f.Destroy()
        del guiDict[num]
    
def onStop():
    """This fonction is called when a script has finished its performance. Can be overriden to call some processes just at the end of a performance. Only work with Ounk GUI."""
    pass
    
def createLadspaPlugin(pluginname='Ounk plugin', controldict={}):
    """Ounk will create a ladspa plugin instead of playing sound. controlDict defines real-time controlers of the plugin.

pluginname = 'Ounk plugin'
controldict = {}

controlDict = {'controlPort': [bus_name, min_range, max_range, log(boolean)],
               'controlPort': ...}"""
    global ladspaName, ladspaDict, ladspaPlugin
    dictBack = {}
    for key in controldict.keys():
        dictBack[key] = controldict[key][0]
        controldict[key][0] = str(_kbusset(controldict[key][0]))
    ladspaName = pluginname
    ladspaDict = controldict
    ladspaPlugin = True
    for key in controldict.keys():
        controldict[key][0] = dictBack[key]

def directOut(input, amplitude=1, duration=None, starttime=0, offset=0, amplitudeVar=None):
    """Audio signals in input are routed to dac with an offset on physical outputs.

input = input sound
amplitude = 1
duration = None
starttime = 0
offset = 0 # first output where to send sound
amplitudeVar = None

* offset can't be a list
** do not use directOut inside midiSynth

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
offset : Output where to send the first audio channel in input. Give the number of the physical output starting at 0. Can't be a list.
amplitudeVar : Name of the control bus multiplying amplitude value.
"""
    if not duration: duration = GDUR
    amp = ''
    vars = [amplitudeVar]
    amplitude, starttime, duration, input = _convertToList(amplitude, starttime, duration, input)
    amplitudeVar = _convertVarToList(amplitudeVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), _len(amplitudeVar))

    if midiSynthesizer:
        raise Error("You can't use directOut inside a midiInstrument!")
        return

    instoffset = int(math.pow(2, len(vars)))
    instrument = _checkInst('directOut', int(_whichVars(vars) + instoffset))
    pval = 6
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("a%d zar p5-%d\n" % (j, voice))
            orchlines.append("a%d = a%d*p4%s\n" % (j, j, amp))
            orchlines.append("gaout%d = a%d + gaout%d\n" % ((j+offset), j, (j+offset)))
        orchlines.append("endin\n")

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'input']
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), str(ainput))
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        line += "\n"
        _routeScoreline(line)

def toDac(input, amplitude=1, duration=None, starttime=0, pan=0.5, amplitudeVar=None, panVar=None):
    """Audio signals in input are routed to dac.

input = input sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
amplitudeVar = None
panVar = None

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
"""
    if not duration: duration = GDUR
    out = 'dac'
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input = _convertToList(amplitude, starttime, duration, pan, input)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d = abus%s%s\n" % (j, i, j, _wrap(input,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('toDac', int(_whichVars(vars) + offset))
    pval = 6
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p5-%d\na%d = ain%d\n" % (j, voice, j, j))
            orchlines.append("a%d = a%d*p4%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def route(input, amplitude=1, duration=None, starttime=0, pan=0.5, amplitudeVar=None, panVar=None, out='dac'):
    """Audio signals in input are routed to out.

input = input sound
amplitude = 1
duration = None
starttime = 0
pan = 0.5
amplitudeVar = None
panVar = None
out = 'dac'

--- PARAMETERS ---

input : Name of the audio input channel.
amplitude : Amplitude (1 is nominal amplitude).
duration : Duration of the function performance in seconds.  Uses global duration if 'None'.
starttime : Starting time of the function performance in seconds.
pan : Position value between 0 and 1.
amplitudeVar : Name of the control bus multiplying amplitude value.
panVar : Name of the control bus controling panning of the sound, overriding pan value.
out = Name of the audio output channel. 'dac' means the output is routed to the sound card.
"""
    if not duration: duration = GDUR
    ipanpval = outpval = 0
    amp = panval = ''
    vars = [amplitudeVar, panVar]
    amplitude, starttime, duration, pan, input = _convertToList(amplitude, starttime, duration, pan, input)
    amplitudeVar, panVar = _convertVarToList(amplitudeVar, panVar)
    seq = max(len(input), len(amplitude), len(starttime), len(duration), len(pan), _len(amplitudeVar), _len(panVar))

    if midiSynthesizer:
        _initAudioBusMidi(out)
        for i in range(seq):
            for j in range(_checkChannels()):
                orchlines.append("a%s%d = abus%s%s\n" % (j, i, j, _wrap(input,i)))
                if amplitudeVar:
                    orchlines.append("a%s%d = a%s%d * %s * kbus%s\n" % (j, i, j, i, _wrap(amplitude,i), _wrap(amplitudeVar,i)))
                else:
                    orchlines.append("a%s%d = a%s%d * %s\n" % (j, i, j, i, _wrap(amplitude,i)))
            _outPanMidiSig(i, out, pan, panVar, _checkChannels(), _checkChannels())
        return

    if out == 'dac': offset = 0
    else: offset = int(math.pow(2, len(vars)))
    instrument = _checkInst('route', int(_whichVars(vars) + offset))
    pval = 6
    if out != 'dac':
        out = _zakset(out)
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        if _checkChannels() > 1:
            ipanpval, pval = _setpan(pval)
        if amplitudeVar:
            pval, amp = _setxxxVar(pval, 'amp')
        if panVar:
            pval, panval = _setpanVar(pval)
        if out != 'dac':
            outpval = pval
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p5-%d\na%d = ain%d\n" % (j, voice, j, j))
            orchlines.append("a%d = a%d*p4%s\n" % (j, j, amp))
        _outPanSig(out, outpval, ipanpval, panval, _checkChannels(), _checkChannels())

    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'amplitude', 'input']
    if _checkChannels() > 1: paramDict[procNum][str(instrument)].append('pan')
    if amplitudeVar: paramDict[procNum][str(instrument)].append('amplitudeVar')
    if panVar: paramDict[procNum][str(instrument)].append('panVar')
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(amplitude,i), str(ainput))
        if _checkChannels() > 1: line += "%s " % _wrap(pan,i)
        if amplitudeVar: line += "%s " % _kbusget(_wrap(amplitudeVar,i))
        if panVar: line += "%s " % _kbusget(_wrap(panVar,i))
        if out != 'dac': line += "%s" % out
        line += "\n"
        _routeScoreline(line)

def udpAudioSend(input, port=9000, host="127.0.0.1", duration=None, starttime=0):
    """Sends audio signal on a UPD port.

input = input sound
port = 9000
host = "127.0.0.1"
duration = None
starttime = 0

port number will be incremented for each channels. Take care when attributing port number if many UdpAudioSend.

* Can not be used inside MIDI instrument"""
    if not duration: duration = GDUR
    input, port, host, duration, starttime  = _convertToList(input, port, host, duration, starttime)
    seq = max(len(input), len(port), len(starttime), len(duration), len(host))

    if midiSynthesizer:
        raise Error("You can't use UdpAudioSend inside a midiInstrument!")
        return

    instrument = _checkInst('UdpAudioSend', 0)
    
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        instrlist.append(instrument)

        for j in range(_checkChannels()):
            voice = _checkChannels() - (j+1)
            orchlines.append("ain%d zar p4-%d\n" % (j, voice))
            orchlines.append("Sport strget p5\n")
            orchlines.append("socksend ain%d, Sport, p6+%d, 200\n" % (j, j))
        orchlines.append("endin\n\n")
            
    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'input', 'host', 'port']
    for i in range(seq):
        ainput = _zakget(_wrap(input,i))
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s "%s" %s\n' % (_wrap(starttime,i), _wrap(duration,i), str(ainput), _wrap(host,i), _wrap(port,i))
        _routeScoreline(line)

def udpAudioReceive(port=9000, duration=None, starttime=0, out='dac'):
    """Receives audio signal from a UPD port.

port = 9000
duration = None
starttime = 0
out = 'dac'

port number will be incremented for each channels. Take care when attributing port number if many UdpAudioReceive.

* Can not be used inside MIDI instrument"""
    if not duration: duration = GDUR
    port, duration, starttime  = _convertToList(port, duration, starttime)
    seq = max(len(port), len(starttime), len(duration))

    if midiSynthesizer:
        raise Error("You can't use UdpAudioReceive inside a midiInstrument!")
        return
    
    if out == 'dac': offset = 0
    else: offset = 1
    instrument = _checkInst('UdpAudioReceive', offset)
    if out != 'dac':
        out = _zakset(out)
        
    if not instrument in instrlist:
        orchlines.append("instr %d\n" % instrument)
        _checkTrigged()
        instrlist.append(instrument)

        if out == 'dac':
            for j in range(_checkChannels()):
                num = j
                orchlines.append("a%d sockrecv p4+%d, 200\n" % (j, j))
                orchlines.append("gaout%s = a%d + gaout%s\n" % (j, j, j))
        else:
            for j in range(_checkChannels()):
                offset = _checkChannels() - (j+1)
                orchlines.append("a%d sockrecv p4+%d, 200\n" % (j, j))
                orchlines.append("zawm a%d, p5-%d\n" % (j, offset))                
        orchlines.append("endin\n\n")
            
    paramDict[procNum][str(instrument)] = ['starttime', 'duration', 'port']
    for i in range(seq):
        if _wrap(duration,i) < 0: line = "i%s " % str(instrument + _infinite())
        else: line = "i%s " % str(instrument)
        line += '%s %s %s ' % (_wrap(starttime,i), _wrap(duration,i), _wrap(port,i))
        if out != 'dac': line += "%s" % out
        line += '\n'
        _routeScoreline(line)

def monitor(host='127.0.0.1', port=15000, address='/monitor', poll=15):
    """Monitors the global linear amplitude at the output of Csound and sends it normalized between 0 and 1 on an OSC port.

host = '127.0.0.1'
port = 15000
address = '/monitor'
poll = 15 # speed of polling in Hz

output is a list of x channels.
"""

    duration = GDUR
    order = [SPEAKERS.index(i) for i in range(len(SPEAKERS))]
    orchlines.append("instr 11000\n")
    orchlines.append(', '.join(['amon%d' % order[i] for i in range(_checkChannels())]) + " monitor\n")
    for i in range(_checkChannels()):
        orchlines.append('kmon%d rms amon%d\n' % (i,i))
        orchlines.append('kmon%d = kmon%d / 23000\n' % (i,i))

    s = "f" * _checkChannels()
    klist = ', '.join(['kmon%d' % i for i in range(_checkChannels())])
    orchlines.append('kran randomh 1, 10000, %f\n' % poll)
    orchlines.append('OSCsend kran, "%s", %s, "%s", "%s", ' % (host, port, address, s) + klist + '\n')
    orchlines.append('endin\n\n')
    scorelines.append('i11000 0 %s\n' % duration)


#####################################################
################### GUI functions ###################
def beginGUI(name='Ounk GUI', size=(260,300)):
    """Begins the definition of a graphical user interface.
    
name = 'Ounk GUI'
size = (260, 300)

return frame object
"""
    import wx
    from ounk.GUIFrame import GUIFrame
    time.sleep(1)
    frame = GUIFrame(None, -1, name, stopCsound, procNum)
    frame.SetSize(wx.Size(size[0], size[1]))
    return frame

def makeButton(frame=None, label='Button', pos=(0,0), function=None):
    """Creates a button.
    
frame = parent_frame
label = 'Button'
pos = (0,0)
function = None

return button object.

function will be called without parameter.
"""    
    from ounk.Widgets import Button
    if frame == None: frame = currentFrame
    button = Button(frame, -1, label, pos=pos, function=function)
    return button

def makeToggle(frame=None, label='Toggle', pos=(0,0), function=None):
    """Creates a Toggle button.
    
frame = parent_frame
label = 'Toggle'
pos = (0,0)
function = None

return toggle object.

function will receive toggle's state (0 or 1).
"""    
    from ounk.Widgets import Toggle
    if frame == None: frame = currentFrame
    toggle = Toggle(frame, -1, label, pos=pos, function=function)
    return toggle
    
def makeSlider(frame=None, label='Slider', init=0, mini=0, maxi=100, pos=(0,0), size=(250,-1), orientation='horizontal', function=None):
    """Creates a slider.
    
frame = parent_frame
label = 'Slider'
init = 0
mini = 0
maxi = 100
pos = (0,0)
size = (250,-1)
orientation = 'horizontal'
function = None

return slider object.

function will receive slider value.
"""
    import wx
    from ounk.Sliders import SimpleSlider
    if frame == None: frame = currentFrame
    if orientation == 'vertical': orient = wx.VERTICAL
    else: orient = wx.HORIZONTAL

    lab = wx.StaticText(frame, -1, label, pos)
    sliderPos = (pos[0], pos[1]+20)
    slider = SimpleSlider(frame, -1, init, mini, maxi, sliderPos, size, orient, function)
    return slider

def makeSpin(frame=None, label='Spin Ctrl', init=0, mini=0, maxi=100, pos=(0,0), size=(100,-1), function=None):
    """Creates a spin controller.
    
frame = parent_frame
label = 'Spin Ctrl'
init = 0
mini = 0
maxi = 100
pos = (0,0)
size = (100,-1)
function = None

return spin object.

function will receive spin controller value.
"""
    import wx
    from ounk.Widgets import SpinCtrl
    
    if frame == None: frame = currentFrame
    lab = wx.StaticText(frame, -1, label, pos)
    spinPos = (pos[0], pos[1]+20)
    spin = SpinCtrl(frame, -1, spinPos, size, min=mini, max=maxi, initial=init, function=function)
    return spin
    
def makeMenu(frame=None, label='Menu', pos=(0,0), choicelist=['1', '2', '3', '4'], function=None):
    """Creates a menu.
    
frame = parent_frame
label = 'Menu'
pos = (0,0)
choicelist = ['1', '2', '3', '4'] # list of anything
function = None

return menu object.

function will receive value as a string.
"""
    import wx
    from ounk.Widgets import Menu 
    if frame == None: frame = currentFrame
    lab = wx.StaticText(frame, -1, label, pos)    
    menuPos = (pos[0], pos[1]+20)    
    menu = Menu(frame, -1, pos=menuPos, choices=choicelist, function=function)
    return menu

def makeMultiSlider(frame=None, init=0, mini=0, maxi=1, sliders=16, valtype='float', label='MultiSlider', pos=(0,0), size=(200,200), orientation='vertical', function=None): 
    """Creates a multi slider window. Function will receive a list of slider values.
    
frame = parent_frame
orientation = 'vertical'
init = 0 # can be a list of values
mini = 0
maxi = 1
sliders = 16 # number of sliders
label = 'MultiSlider'
pos = (0,0)
size = (200,200)
valtype = 'float' # 'float' or 'int'
function = None

function will receive a list of slider values.
"""

    import wx
    from ounk.Sliders import MultiSlider
    from types import IntType, FloatType
    
    if frame == None: frame = currentFrame
    if valtype == 'float': t = FloatType
    else: t = IntType
    lab = wx.StaticText(frame, -1, label, pos)    
    multiPos = (pos[0], pos[1]+20) 
    slider = MultiSlider(frame, init, mini, maxi, pos=multiPos, size=size, sliders=sliders, valtype=t, orient='vertical', function=function)
    
def makeXYSlider(frame=None, label='XY Slider', pos=(0,0), size=(200,200), mini=0, maxi=1, function=None): 
    """Creates an XY slider window. Function will receive a list of (x,y) position values.
    
frame = parent_frame
label = 'XY Slider'
pos = (0,0)
size = (200,200)
mini = 0
maxi = 1
function = None

function will receive a list of X - Y values.
"""

    import wx
    from ounk.Sliders import XYSlider

    if frame == None: frame = currentFrame
    lab = wx.StaticText(frame, -1, label, pos)    
    XYPos = (pos[0], pos[1]+20)     
    slider = XYSlider(frame, mini, maxi, pos=XYPos, size=size, function=function)

def makeRangeSlider(frame=None, init=[0,.5], mini=0, maxi=1, valtype='float', label='RangeSlider', pos=(0,0), size=(200,20), function=None): 
    """Creates a range slider window. Function will receive a list of slider's two values.
    
frame = parent_frame
init = [0, 0.5]
mini = 0
maxi = 1
valtype = 'float' # 'float' or 'int'
label = 'RangeSlider'
pos = (0,0)
size = (200,200)
function = None

function will receive a list of slider's two values.
"""

    import wx
    from ounk.Sliders import RangeSlider
    from types import IntType, FloatType
    
    if frame == None: frame = currentFrame
    if valtype == 'float': t = FloatType
    else: t = IntType
    lab = wx.StaticText(frame, -1, label, pos)    
    rangePos = (pos[0], pos[1]+20) 
    slider = RangeSlider(frame, init, mini, maxi, pos=rangePos, size=size, valtype=t, function=function)
    
def makeCircleSlider(frame=None, label='Circle Slider', pos=(0,0), size=(200,200), mini=0, maxi=1, function=None): 
    """Creates a circle slider window. Function will receive a list of (x,y) position values.
    
frame = parent_frame
label = 'Circle Slider'
pos = (0,0)
size = (200,200)
mini = 0
maxi = 1
function = None

function will receive a list of X - Y values.
"""

    import wx
    from ounk.Sliders import CircleSlider

    if frame == None: frame = currentFrame
    lab = wx.StaticText(frame, -1, label, pos)    
    circlePos = (pos[0], pos[1]+20)     
    slider = CircleSlider(frame, mini, maxi, pos=circlePos, size=size, function=function)

def makeFractal(function=None): 
    """Create an Fractal image generator window. Image can be scan and used for musical control.
    
function = None

return fractal object

function is called on each modification applied to the fractal image.

Methods of the fractal object:

getDepth: Return a value between 0 and 1 representing the quantity of black on the screen.

scanImage: Return a list of 0 (white) and 1 (black) for all pixels in the specified column. The list has a length of 500.

* be shure to stop the process before closing the fractal window *"""

    import wx
    import ounk.Fractals as Fractals

    fractal = Fractals.Fractals(None, -1, title=Fractals.NAME, size=(770, 600), function=function)
    fractal.Show()
    return fractal
    
# not yet ready!
def makeSpaceSlider(frame=None, label='Space Slider', pos=(0,0), size=(200,200), mini=0, maxi=1, function=None): 
    """Create an Space slider window. Function will receive a list of (x,y) position values.
    
frame = parent_frame
label = 'Space Slider'
pos = (0,0)
size = (200,200)
mini = 0
maxi = 1
function = None

function will receive a list of X - Y values.
"""

    import wx
    from ounk.Sliders import SpaceSlider

    if frame == None: frame = currentFrame
    lab = wx.StaticText(frame, -1, label, pos)    
    circlePos = (pos[0], pos[1]+20)     
    slider = SpaceSlider(frame, mini, maxi, pos=circlePos, size=size, function=function)
     
def endGUI(frame):
    """Closes and displays the graphical user interface.
    
frame = frame_to_show"""
    frame.Show(True)
    guiDict[procNum].append(frame)

class Gui:
    """Begins the definition of a graphical user interface.
    
name = 'Ounk GUI'
size = (260, 300)

return frame object
"""
    def __init__(self, name='Ounk GUI', size=(260,300)):
        global currentFrame
        import wx
        from ounk.GUIFrame import GUIFrame
        time.sleep(1)
        currentFrame = GUIFrame(None, -1, name, stopCsound, procNum)
        currentFrame.SetSize(wx.Size(size[0], size[1]))
    
    def __enter__(self):
        pass

    def __exit__(self, type, value, traceback):
        global currentFrame
        currentFrame.Show(True)
        guiDict[procNum].append(currentFrame)
        currentFrame = None

#####################################################
####################### INFO ########################
LIB_INFO = {'General': {'setSoundPath': setSoundPath, 'setImpulsePath': setImpulsePath, 'setSoundfontPath': setSoundfontPath, 'setMidiPath': setMidiPath,
                     'getSoundPath': getSoundPath, 'getImpulsePath': getImpulsePath, 'getSoundfontPath': getSoundfontPath, 'getMidiPath': getMidiPath,
                    'getSoundList': getSoundList, 'getSoundInfo': getSoundInfo, 'setAudioAttributes': setAudioAttributes, 'getAudioAttributes': getAudioAttributes,
                    'clear': clear, 'setGlobalDuration': setGlobalDuration, 'speakersConfig': speakersConfig, 'setChannels': setChannels,
                    'setMidiDevice': setMidiDevice, 'setAudioDevice': setAudioDevice, 'onStop': onStop},
            'Sources': {'sine': sine, 'square': square, 'sawtooth': sawtooth, 'waveform': waveform, 'pluckedString': pluckedString, 'playSound': playSound,
                        'inputMic': inputMic, 'whiteNoise': whiteNoise, 'pinkNoise': pinkNoise, 'freqMod': freqMod, 'voiceSynth': voiceSynth,
                        'soundfont': soundfont, 'soundfontMidi': soundfontMidi, 'bell': bell, 'train': train, 'pulsar': pulsar},
            'Effects': {'ringMod': ringMod, 'resonator': resonator, 'harmonizer': harmonizer, 'distortion': distortion, 'compressor': compressor,
                        'didjeridu': didjeridu, 'delay': delay, 'fold': fold, 'vdelay': vdelay, 'phaser': phaser, 'flanger': flanger, 'vocoder': vocoder},
            'Filters': {'lowpass': lowpass, 'highpass': highpass, 'bandpass': bandpass, 'dcblock': dcblock, 'resFilter': resFilter, 'eqFilter': eqFilter,
                        'bandreject': bandreject},
            'Reverbs': {'waveguideReverb': waveguideReverb, 'infiniteReverb': infiniteReverb, 'reverb': reverb, 'convolveReverb': convolveReverb},
            'Spectral': {'crossSynth': crossSynth, 'blur': blur, 'freeze': freeze, 'smooth': smooth, 'transpose': transpose, 'arpegiator': arpegiator,
                         'reSynth': reSynth, 'maskFilter': maskFilter, 'fftBandpass': fftBandpass, 'fftBandreject': fftBandreject, 'fftBufRead': fftBufRead,
                         'fftBufBlur': fftBufBlur, 'fftBufAdsyn': fftBufAdsyn},
            'Analysis': {'pitchAmp': pitchAmp, 'centroid': centroid, 'rms': rms, 'attackDetector': attackDetector},            
            'GenTables': {'genAdsr': genAdsr, 'genLineseg': genLineseg, 'genExpseg': genExpseg, 'genWaveform': genWaveform, 'genPulsarWave' : genPulsarWave,
                        'genWindow': genWindow, 'genSoundTable': genSoundTable, 'genDataTable': genDataTable, 'tableMorphing': tableMorphing,
                        'genRhythmTable': genRhythmTable, 'recordBuffer': recordBuffer, 'reGenWaveform': reGenWaveform, 'reGenDataTable': reGenDataTable,
                        'reGenSoundTable': reGenSoundTable, 'reGenWindow': reGenWindow, 'reGenLineseg': reGenLineseg, 'reGenExpseg': reGenExpseg,
                        'reGenAdsr': reGenAdsr, 'genDiscreetTable': genDiscreetTable, 'reGenDiscreetTable': reGenDiscreetTable, 'genDataFileTable': genDataFileTable,
                        'reGenDataFileTable': reGenDataFileTable},
            'Midi Synth': {'beginMidiSynth': beginMidiSynth, 'endMidiSynth': endMidiSynth, 'splitKeyboard': splitKeyboard,
                           'splitVelocity': splitVelocity, 'midiSynthGetBus': midiSynthGetBus, 'readMidiFile': readMidiFile,
                           'midiSynthCtl': midiSynthCtl},
            'Sequencer': {'beginSequencer': beginSequencer, 'endSequencer': endSequencer, 'sequencerPitchTable': sequencerPitchTable,
                        'seqParameterTable': seqParameterTable},
            'Loops':    {'beginLoop': beginLoop, 'endLoop': endLoop},            
            'Controls': {'linsegr': linsegr, 'expsegr': expsegr, 'busMix': busMix, 'readTable': readTable, 'randomi': randomi,
                         'mouse': mouse, 'rando': rando, 'randomh': randomh, 'keyPressed': keyPressed, 'midiCtl': midiCtl, 'printMidiCtl': printMidiCtl,
                         'oscReceive': oscReceive, 'oscSend': oscSend, 'vibrato': vibrato, 'metro': metro, 'lfo': lfo, 'lfo2': lfo2, 'midiTrigger': midiTrigger,
                         'randomChoice': randomChoice, 'weightedRandomChoice': weightedRandomChoice, 'midiTriggerInc': midiTriggerInc, 'trigRandom': trigRandom,
                         'spline': spline, 'oscTriggerSend': oscTriggerSend, 'busScale': busScale, 'trigEnvelope': trigEnvelope, 'discreetTableLoop': discreetTableLoop,
                         'jitter': jitter, 'busMapper': busMapper},
            'Table process': {'soundTableRead': soundTableRead, 'looper': looper, 'warper': warper, 'granulator': granulator, 'granulator2': granulator2,
                              'granulator3': granulator3, 'tablesMod': tablesMod, 'flooper': flooper},
            'Sampling': {'recordAndLoop': recordAndLoop},
            'Algorithmic': {'chord': chord, 'scale': scale, 'drunk': drunk, 'droneAndJump': droneAndJump, 'repeater': repeater, 'loopseg': loopseg,
                            'next': Drunk.next, 'markov': markov, 'mkStartPlayback': Markov.mkStartPlayback, 'mkStartRecord': Markov.mkStartRecord,
                            'mkSetList': Markov.mkSetList, 'mkRecord': Markov.mkRecord, 'mkChangeOrder': Markov.mkChangeOrder, 'mapper': mapper,
                            'midiToHertz': midiToHertz, 'midiToTranspo': midiToTranspo, 'line': line, 'getValue': Liner.getValue, 'oneCall': oneCall,
                            'logistic': logistic, 'changeConstant': Logistic.changeConstant, 'changeInitial': Logistic.changeInitial, 'henon': henon,
                            'semitoneToTranspo': semitoneToTranspo},
            'Python Inst': {'beginPythonInst': beginPythonInst, 'endPythonInst': endPythonInst},
            'Patterns': {'pattern': pattern, 'changePattern': MyTimer.changePattern, 'changeTime': MyTimer.changeTime,
                        'getBeat': MyTimer.getBeat, 'getBar': MyTimer.getBar, 'getTime': MyTimer.getTime, 'sendEvent': sendEvent,
                        'rhythmPattern': rhythmPattern, 'regenerate': RhythmPattern.regenerate, 'sendOscControl': sendOscControl, 
                        'sendCsoundMsg': sendCsoundMsg, 'sendOscTrigger': sendOscTrigger},
            'GUI': {'beginGUI': beginGUI, 'endGUI': endGUI, 'makeButton': makeButton, 'makeToggle': makeToggle,
                    'makeSlider': makeSlider, 'makeMenu': makeMenu, 'makeMultiSlider': makeMultiSlider, 'makeXYSlider': makeXYSlider,
                    'makeCircleSlider': makeCircleSlider, 'makeSpin': makeSpin, 'makeRangeSlider': makeRangeSlider},
            'Custom Inst': {'myInstrument': myInstrument},
            'Spatialisation': {'spat1to4': spat1to4, 'pan1to2': pan1to2, 'pan1to4': pan1to4, 'pan1to8': pan1to8, 'pan2to4': pan2to4, 
                               'pan2to8': pan2to8, 'pan4to8': pan4to8, 'panner': panner},
            'Output': {'startCsound': startCsound, 'stopCsound': stopCsound, 'toDac': toDac, 'getPid': getPid, 'recordPerf': recordPerf,
                       'route': route, 'udpAudioSend': udpAudioSend, 'udpAudioReceive': udpAudioReceive, 'createLadspaPlugin': createLadspaPlugin,
                       'directOut': directOut, 'monitor': monitor},
            'Trigged Inst': {'beginTrigInst': beginTrigInst, 'endTrigInst': endTrigInst}}
    
LIB_DOC = {'General': """Set of functions to customize the environment, ie: path management, audio attributes and global durations.""",
            'Sources': """A set of functions to generate audio samples. Synthesis, sound playback from disk, soundfonts, etc.  Routing is done by setting the 'out' parameter.""",
            'Effects': """A set of functions that take audio samples as input, as defined by the 'input' parameter, and applies signal processing functions to them. Routing is done by setting the 'out' parameter.""",
            'Filters': """A set of functions that take audio samples as input, as defined by the 'input' parameter, and applies filtering to them. Routing is done by setting the 'out' parameter.""",    
            'Reverbs': """A set of functions that take audio samples as input, as defined by the 'input' parameter, and applies reverberation to them. Routing is done by setting the 'out' parameter.""",    
            'Spectral': """A set of FFT signal procesing functions. Perform FFT analysis on input signals, apply transformations, and perform IFFT to reconstruct audio signals. Routing is done by setting the 'out' parameter.""",
            'Analysis': """A set of functions to analyse a given attribute of an audio input signal. Input signals are defined by setting the 'input' parameter. A control signal is sent by these functions and can be routed to any 'xxxVar' parameter by setting the 'bus' parameter.""",
            'GenTables': """This set of functions create and fill Csound tables. Csound tables are memory buffers containing sound samples, discrete data values, waveforms, envelopes, etc. Functions return the csound table number, which can be assigned to a 'table' parameter.""",
            'Midi Synth': """A set of functions to build MIDI synthesizers. Every process between function flags 'beginMidiSynth' and 'endMidiSynth' will respond to noteon and noteoff triggers. Routing of audio samples and controller values inside a Midi Synth are valid only for the synthesizer. Routing of the synthesizer sound can be done by setting the 'out' parameter of the 'endMidiSynth' function.""",
            'Sequencer': """A set of functions to build a step sequencer. Every process between function flags 'beginSequencer' and 'endSequencer' will respond to a metronome trigger assigned in 'beginSequencer'.""",
            'Loops': """A set of functions to create note loops, providing control on note amplitude and duration over the full duration of the loop.""",
            'Controls': """A set of functions to define control values that change over time. These functions send a control signal that can be routed to any 'xxxVar' parameter by setting the 'bus' parameter.""",
            'Table process': """A set of functions that perform actions on audio samples stored in a Csound table with 'genSoundTable'. Routing is done by setting the 'out' parameter.""",
            'Sampling': """A set of functions to record audio signals in a temporary buffer and manipulate it.""",
            'Algorithmic': """This set of functions are devoted to the creation of algorithmic musical patterns. Some functions create objets with their own methods to control musical behavior. These functions are used in the Python environment to generate, in real-time, the parmeters of events sent to Csound. Must be used with functions in 'Pattern' and 'Python Inst' categories.""",
            'Python Inst': """This set of functions create an instrument that waits for events from Csound stdin ('sendEvent' is the function to send an event to the Csound stdin). All function parameters in the instrument can be modified by passing a dictionary of parameters to 'sendEvent'.""",
            'Patterns': """A pattern objet is a Python timer that follow a rhythm pattern to call a user-defined function. This function can be used to send events to a Python Inst.""",
            'GUI': """A set of functions to create a graphical interface for the control of sound parameters.""",
            'Custom Inst': """This set of functions allows the user to import a csound instrument from a text file for use inside the Ounk framework.""",
            'Spatialisation': """A set of functions to place sound in space.""",
            'Output': """Management of Csound. Start, stop, recording, management of multiple processes, etc.""",
            'Trigged Inst': """A set of functions to build a triggered instrument. The instrument can be started and stoped several times by a trigger signal."""}
